ANDROID - определение цвета с помощью openCV - как?

моя цель - отобразить обмолоченное изображение с использованием цветового пространства HSV таким образом, чтобы отображались только желтые объекты. я использую этот код (на основе кода, заданного образцами Android openCV 2.3.1):

protected Bitmap processFrame(VideoCapture capture) {
    //capture.retrieve(mGray, Highgui.CV_CAP_ANDROID_GREY_FRAME);
    //Imgproc.cvtColor(mGray, mRgba, Imgproc.COLOR_GRAY2RGBA, 4);

    capture.retrieve(mHSV, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA);
    Imgproc.cvtColor(mHSV, mRgba, Imgproc.COLOR_RGB2HSV, 4);
    //Core.inRange(mRgba, new Scalar(20, 100, 100), new Scalar(30, 255, 255), mRgba);

    Bitmap bmp = Bitmap.createBitmap(mRgba.cols(), mRgba.rows(), Bitmap.Config.ARGB_8888);

    if (Utils.matToBitmap(mRgba, bmp))
        return bmp;

    bmp.recycle();
    return null;
}

базовый (абстрактный) класс содержит метод «выполнить»:

protected abstract Bitmap processFrame(VideoCapture capture);

public void run() {
...
bmp = processFrame(mCamera);
...
canvas.drawBitmap(bmp, (canvas.getWidth() - bmp.getWidth()) / 2, (canvas.getHeight() - bmp.getHeight()) / 2, null);
...
}

я получаю это искаженное превью, которое, я думаю, я могу понять (формат HSV), но почему оно повторяется (я рисую зеленую линию, чтобы подчеркнуть это) 4 раза? а что за черная горизонтальная линия? введите здесь описание изображениячто я делаю не так?

и последнее, в чем логика:

Imgproc.cvtColor(mHSV, mRgba, Imgproc.COLOR_RGB2HSV, 4);

почему это COLOR_RGB2HSV? разве это не должно быть COLOR_HSV2RGB?

Допустим, я решил эту проблему, как я могу сделать изображение уровня серого с желтыми объектами в их родном цвете? я думал использовать метод Core.inRange(), но когда я это делаю, я получаю черный экран.

да, наверное, я выгляжу полным придурком, но мне нужно с чего-то начинать, не так ли?

10x!

Обновление 1: я пытался сделать RGB->HSV->RGB следующим образом:

 @Override
protected Bitmap processFrame(VideoCapture capture) {
    //capture.retrieve(mGray, Highgui.CV_CAP_ANDROID_GREY_FRAME);
    //Imgproc.cvtColor(mGray, mRgba, Imgproc.COLOR_GRAY2RGBA, 4);

    capture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGB);
    Imgproc.cvtColor(mRgba, mHSV, Imgproc.COLOR_RGB2HSV,0);
    //Imgproc.cvtColor(mRgba, mRgba, Imgproc.COLOR_BGR2RGB, 4);
    //Core.inRange(mRgba, new Scalar(20, 100, 100), new Scalar(30, 255, 255), mRgba);
    Imgproc.cvtColor(mHSV,mRgba , Imgproc.COLOR_HSV2RGB,0);

    Bitmap bmp = Bitmap.createBitmap(mRgba.cols(), mRgba.rows(), Bitmap.Config.ARGB_8888);

    if (Utils.matToBitmap(mRgba, bmp))
        return bmp;

    bmp.recycle();
    return null;
}

и я получил: введите здесь описание изображения

?

Обновление 2:

я наконец понимаю, что перед установкой кадра его нужно преобразовать в пространство RGBA. поэтому я теперь попробовал порог с кодом следующим образом:

capture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA);
    Imgproc.cvtColor(mRgba, mHSV, Imgproc.COLOR_RGB2HSV,0);
    Core.inRange(mHSV, new Scalar(20, 100, 100), new Scalar(30, 255, 255), mHSVThreshed);
    Imgproc.cvtColor(mHSVThreshed, mRgba, Imgproc.COLOR_HSV2RGB, 0);
    Imgproc.cvtColor(mRgba, mRgba, Imgproc.COLOR_RGB2RGBA, 0);
    Bitmap bmp = Bitmap.createBitmap(mRgba.cols(), mRgba.rows(), Bitmap.Config.ARGB_8888);

но теперь это дает мне принудительное отключение ... есть идеи?


person gor    schedule 25.02.2012    source источник
comment
Я знаю, что это было некоторое время назад, и это неправильный способ спросить, но вы сделали учебник для этого? поскольку я не могу заставить VideoCapture работать, я был бы рад, если бы вы могли предоставить свой код или части вашего кода на github. Большое спасибо   -  person user1651460    schedule 03.01.2014
comment
Привет. Im really sorry but it has been a while since iv работал с openCV, плюс у меня больше нет кода. Советую посмотреть здесь: docs.opencv .org/doc/tutorials/highgui/video-write/. Удачи, трудолюбие рано или поздно окупится :)   -  person gor    schedule 05.01.2014


Ответы (4)


Я думаю, что mHSVThreshed - это бинарный мат

так что, может быть, эта строка:

Imgproc.cvtColor(mHSVThreshed, mRgba, Imgproc.COLOR_HSV2RGB, 0);

следует изменить на:

Imgproc.cvtColor(mHSVThreshed, mRgba, Imgproc.COLOR_GRAY2RGB, 0);

Я тоже потратил много времени на решение проблемы "показания"...

надеюсь на эту помощь...

person Ethan Chen    schedule 27.02.2012
comment
Эй, я хочу добавить матрицу в выделенную часть изображения, вы можете мне помочь? - person Smit Patel; 09.05.2014
comment
Что за матрица? Вы имеете в виду нарисовать на нем что-то вроде AR? - person Ethan Chen; 17.05.2014

друзья. Представляю вам результат 1 месяца кропотливой работы и помощи друзей из-за океана: введите сюда описание изображения

Итан был прав. но код нуждался в некоторой фиксации.

код:

    capture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_BGRA);
    Imgproc.cvtColor(mRgba, mHSV, Imgproc.COLOR_BGR2HSV,3);
    Core.inRange(mHSV, new Scalar(0, 100, 30), new Scalar(5, 255, 255), mHSVThreshed);
    Imgproc.cvtColor(mHSVThreshed, mRgba, Imgproc.COLOR_GRAY2BGR, 0);
    Imgproc.cvtColor(mRgba, mRgba2, Imgproc.COLOR_BGR2RGBA, 0);
    Bitmap bmp = Bitmap.createBitmap(mRgba2.cols(), mRgba2.rows(), Bitmap.Config.ARGB_8888);


    if (Utils.matToBitmap(mRgba2, bmp))...

во-первых, мат имеет двоичный код 0 или 255, поэтому преобразование в уровень серого более «естественно». во-вторых, преобразование из HSV в RGB на самом деле является HSV-BGR!!. и последнее, что предварительный просмотр ожидает растровое изображение RGBA.

Это оно. надеюсь, что другие могут извлечь выгоду из этого поста. ШАЛОМ!

person gor    schedule 27.02.2012
comment
Слава, это была большая помощь! - person octopi; 19.04.2012
comment
@gor не могли бы вы добавить значения mRgba, mHSV, mHSVThreshed, mRgba2? - person dvrm; 17.12.2015
comment
не уверен, что понимаю вопрос + это было опубликовано много лет назад, и код больше не доступен. - person gor; 18.12.2015
comment
для многих Imgproc.cvtColor... поэтому для inRange нам просто нужен HSC в качестве ввода и GRAY в качестве вывода (RGB2HSV) и (GRAY2RGB) - person user25; 06.03.2017

Насколько я понимаю, вы получаете кадр изображения в формате RGBA и сохраняете его под именем «mHSV».

capture.retrieve(mHSV, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA);

поэтому вы должны хранить его как mRgba

в cvtColor вам нужно преобразовать его в HSV через COLOR_RGBA2HSV. Предполагая, что вы изменили имена, это будет:

Imgproc.cvtColor(mRgba, mRSV, Imgproc.COLOR_RGB2HSV, 0);

И я предполагаю, что это повторение изображений исходит из «4» в вашей функции cvtColor, поскольку ваше изображение HSV будет иметь только 3 канала. Поместите туда 0, и он должен быть обнаружен автоматически...

Я надеюсь, что это помогает...

person florianbaethge    schedule 25.02.2012
comment
Эй, именно то, что я имел в виду, но с лучшими объяснениями: p - person jlengrand; 25.02.2012
comment
Вы пытались отладить, чтобы узнать, где именно выдает ошибку? Например, какие команды выполняются без ошибок и где происходит выход? - person florianbaethge; 26.02.2012
comment
я сделал. по-видимому, приложение никогда не доходит до строки: Imgproc.cvtColor(mRgba, mRgba, Imgproc.COLOR_BGR2RGBA, 0); - person gor; 26.02.2012
comment
до этого основной поток выполняет mCamera.grab() и через пару секунд после этого просто падает.. - person gor; 26.02.2012
comment
Совсем не уверен, но может быть OpenCV не нравится, когда указатели ввода и вывода на самом деле являются одним и тем же объектом? Оба мРгба... - person florianbaethge; 26.02.2012

почему это COLOR_RGB2HSV? разве это не должно быть COLOR_HSV2RGB?

Я бы сказал, что должен :). Похоже, проблема в том, как opencv захватывает пиксели. Убедитесь, что входное и выходное изображения имеют одинаковый размер и количество каналов.

Этот

capture.retrieve(mHSV, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA);

Мне это тоже кажется странным. Вы сохраняете изображение RGBA, которое вы получаете, в изображение в формате HSV? Это объяснило бы проблему. Попробуйте сделать что-то вроде этого: RGB (получение захвата) => HSV (цвет cvt) => определение цвета => RGB (снова цвет cvt)

person jlengrand    schedule 25.02.2012
comment
я знаю, что это выглядит проводным, но когда я пытаюсь преобразовать: capture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA); Imgproc.cvtColor(mRgba, mHSV, Imgproc.COLOR_HSV2RGB_FULL, 4); это не работает... - person gor; 25.02.2012