Перейти к содержимому
Compvision.ru
compblinder

Фильтрация по цвету

Recommended Posts

Здравствуйте:)Помогите нубу приобщиться к мудрости:)

Начал вникать в машинное зрение вообще и OpenCV в частности с этого понельника, поэтому заранее извиняюсь за кривую терминологию и т.д. и т.п.

Пишу программу под Андроид на Jawa, одной из функций приложения будет сравнение формы некоего объекта на получаемом изображении (с камеры, СД-карты не важно) с контурами в эталонной БД и определения 3-х наиболее сходных.

Пока задание в процессе проработки, но скорее всего варианта будет два - на анализируемом фото пользователь пальцем или стилом сам обводит силуэт нужного объекта, используя определенный цвет пера - тут с точки зрения OpenCV все проще, поскольку сразу будет получать голый силуэт на чистом фоне (как я предполагаю на данный момент:)) для дальнейшей обработки.

Второй вариант (наверное придется использовать для сложных форм и точного сравнения) - пользователь будет выделять объект в графическом редакторе все тем же определенным цветом, сохранять изображение и уже в таком виде передавать приложению. В этом случае я для надежности решил действовать тупо в лоб - брать изображение, очищать все пиксели имеющии отличный от заданного цвет и уже полученный голый силуэт переводить в серый, инвертировать и применять findContour(). И вот уже второй день головой в монитор бьюсь с этой фильтрацией по цвету.

Вот мой код:

public void GetContour(Bitmap bt)

{


    Mat matproc = new Mat();

    Mat matproc1 = new Mat();


    //bt = bt.copy(Bitmap.Config.ARGB_8888, true);


    Utils.bitmapToMat(bt,matproc);

    Utils.bitmapToMat(bt,matproc1);



    Log.e(TAG, "0");


    /*for(int i=0;i<matproc.height();i++){

        for(int j=0;j<matproc.width();j++){

            if (!(matproc.get(i, j)[0] == 0)&&(matproc.get(i, j)[1] == 0)&&(matproc.get(i, j)[2] > 192))//double y = 0.3 * matproc.get(i, j)[0] + 0.59 * matproc.get(i, j)[1] + 0.11 * matproc.get(i, j)[2];

            matproc.put(i, j, new double[]{0, 0, 0});


    }*/



    Imgproc.cvtColor(matproc1, matproc, Imgproc.COLOR_BGR2HSV,0);

    Core.inRange(matproc, new Scalar(0, 0, 255), new Scalar(5, 5, 255), matproc1);

    //Imgproc.cvtColor(matproc1, matproc, Imgproc.COLOR_GRAY2BGR, 0);

    //Imgproc.cvtColor(matproc, matproc1, Imgproc.COLOR_BGR2RGBA, 0);

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



    currentImage1 = Bitmap.createBitmap(matproc1.cols(),

            matproc1.rows(), Bitmap.Config.ARGB_8888);

    Utils.matToBitmap(matproc1,currentImage1);

    im1.setImageBitmap(currentImage1);

}

а вот что приходит приложению и что получается на выходе:

1_online.jpg (не разобрался я с хостингом, если кому интересно картинка в файле прикреплена)

справа изображение на экране исходного файла - файл я создал в Paint, несколько фигур нарисовал пером красного цвета (в Paint обозначалось как 255,0,0) и две фигуры для теста нарисовал зеленым и синим пером, после чего сохранил его в формате JPG. Андроид файл открывает стандартными средствами - через битовый поток считывает его в bitmap. Этот самый битмап соотвественно передается в функцию GetContour, которая его преобразует в матрицу, пропускает через inRange и выводит на левый контрол.

Я наверное не понимаю чего-то очень очевидного, но почему любые комбинации цветов в inRange в результате дают либо объекты всех цветов либо черный фон и никогда не выводят исключительно красные фигуры?

Второй вопрос в догонку: если закрыть глаза на неработающую фильтрацию и пропустить матрицу дальше, через стандартные сглаживания, инверсии, пороговое преобразование, cvCanny и наконец findContour, а потом вывести контур с наименьшей площадью через drawContour, то в результате получим примерно тоже изображение, что выше - т.е. правильно ли я понимаю, что для получения доступа к контуру отдельной фигуры потребуются дальнейшие вычисления или я опять что-то не так делаю?

post-6262-0-84479500-1356609644_thumb.jp

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Так у Вас же в HSV все перед фильтрацией переводится.

А фильтровать Вы вроде как собирались по R,G,B компонентам.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Так у Вас же в HSV все перед фильтрацией переводится.

А фильтровать Вы вроде как собирались по R,G,B компонентам.

спасибо за внимание:)

дело в том, чтог если в HSV не перводить вообще постоянно черный фон:) inRange по умолчанию работает только с HSV?

Раз уж до меня гуру снизошел, то хотел бы уточнить по вопросу с контурами - если мы на вход функции findContours подаем матрицу некоего изображения на котором имеется набот идеальных фигур (круг, квадрат, прямоугольник) - у всех толщина линий 1 пиксель, никто ни с кем не пересекается, все находятся на нектором расстоянии друг от друга. Что будет представлять из себя контур номер Х полученный из этой функции? Отдельно взятую фигуру или это может быть скажем круг и ближайшая к нему сторона квадрата слева/треугольника справа?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

По поводу InRange.

Проведите эксперимент возьмите маленькое изображение, скажем 8 на 8 точек, выведите его в консоль при помощи cout << Img.

Посмотрите чему равны значения в матрице.

InRange работает с матрицами и ничего не знает об их формате, следовательно что то у Вас со значениями элементов не то.

Проблемы с тонкими контурами могут возникать при сжатии изображений методами сжатия с потерями, например JPG (они размываются или просто исчезают). Сохраните картинку из paint в png, tiff или bmp формате.

Что касается контуров, то для того случая который Вы описали получите набор отдельных контуров для каждой фигуры (по одному (внешний) или по два (внутренний и внешний), в зависимости от установленных ключей).

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте учётную запись или войдите для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать учётную запись

Зарегистрируйтесь для создания учётной записи. Это просто!

Зарегистрировать учётную запись

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас


  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу

×