Как сегментировать область интереса на изображении листа

Цель: я хочу обнаружить определенные области изображений листьев. Я обнаружил связанные с этим проблемы, близкие к этому сегментировать объект (лист), который находится на белой бумаге, используя обработку изображения (удаление листа с белого фона), но мой выходит за его пределы, он направлен на извлечение/сегментацию больной области листа.

Проблема: как точно сегментировать и выделить больные участки листа на изображении.

Моя попытка:
1. функция inRange() OpenCV — порог зеленого цвета, чтобы я не делал несколько значений inRange для незеленых областей (коричневый, серый и т. д.) и, надеюсь, я уберу зеленый цвет; Я применил размытие по Гауссу, конвертировал из RGB в HSV перед сегментацией

Ссылка на файлы входных данных image1, image2 и результатов:
Image1: Результат: Зеленый цвет был сегментирован( подумал не совсем точно), но я пока не знаю, как выделить незеленые области (как следующий шаг)

Изображение 2: Результат: Маленькие темные круги были включены/считались зелеными, что предположительно не должно

Я новичок в OpenCV (а также в C++), и я прочитал несколько методов (таких как методы кластеризации fuzzy-c и k-means и т. д.) для сегментации, но я не могу решить, какой метод сегментации использовать для моих изображений. Я также узнал из прочитанных статей, что не существует такой вещи, как универсальная техника сегментации, которую можно было бы применить ко всем изображениям.

Таким образом, я хотел бы знать, какой метод (метод кластеризации? Основанный на области? Гистограмма? и т. д.) или процесс лучше всего применять для типов изображений, которые у меня есть, чтобы точно сегментировать указанные изображения.

Большое Вам спасибо.


person user3339658    schedule 22.02.2014    source источник


Ответы (1)


Просто попробуйте выполнить следующие шаги

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

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

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

Приведенные ниже фрагменты кода сделают вышеописанное

Mat thr;
Mat src=imread("image2.png",1); //Your processed  image
cvtColor(src,thr,CV_BGR2GRAY);
threshold(thr,thr,180,255,THRESH_BINARY_INV);

vector< vector <Point> > contours; // Vector for storing contour
vector< Vec4i > hierarchy;
int largest_contour_index=0;
int largest_area=0;
Mat mask(src.rows,src.cols,CV_8UC1,Scalar::all(0)); //create destination image
findContours( thr.clone(), contours, hierarchy,CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE ); // Find the contours in the image
 for( int i = 0; i< contours.size(); i++ ) // iterate through each contour.
  {
   double a=contourArea( contours[i],false);  //  Find the area of contour
   if(a>largest_area){
   largest_area=a;
   largest_contour_index=i;                //Store the index of largest contour
   }
  }
 drawContours( mask,contours, largest_contour_index, Scalar(255,255,255),CV_FILLED, 8, hierarchy ); // Draw the largest contour using previously stored index.
 int dilation_size = 2;
 Mat element = getStructuringElement( MORPH_RECT,
                                      Size( 2*dilation_size + 1, 2*dilation_size+1 ),
                                      Point( dilation_size, dilation_size ) );
 erode( mask, mask, element );

Извлечь зеленую область:- Здесь вы должны использовать цветовое пространство hsv, inrange и т. д., как указано в вашем вопросе.

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

Mat HSV,hsv_thr,dst;
cvtColor(src,HSV,CV_BGR2HSV);
inRange(HSV,Scalar(20,10,10),Scalar(90,255,255),hsv_thr);

bitwise_not для изображения выше:- Здесь вы должны использовать маску, созданную выше.

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

  bitwise_not(hsv_thr, dst, mask);

Нарисуйте больную область:- Здесь снова вам нужно найти контур, нарисовать контур и т. д.

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

findContours( dst.clone(), contours, hierarchy,CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE ); // Find the contours in the image
     for( int i = 0; i< contours.size(); i++ ) // iterate through each contour.
      drawContours( src,contours, i, Scalar(0,0,255),1, 8, hierarchy ); 

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

Надеюсь, эти полезные...

person Haris    schedule 22.02.2014
comment
это было то, что мне действительно нужно. Это действительно очень полезно. Я просто хочу спросить, есть ли другие форматы для области интереса (не зеленые)? Мне нужна версия roi в оттенках серого или цветное изображение (не бинарное) для дальнейшей обработки. - person user3339658; 25.02.2014
comment
используя этот ответ здесь [ссылка] (stackoverflow.com/questions/10176184/), я попытался получить область внутри контура (где только roi видны, остальные черные), но мне удалось получить только область в пределах первого контура изображения, а не все контуры. Можете ли вы дать мне несколько советов о том, как мне получить содержимое всех контуров? заранее большое спасибо. :) - person user3339658; 25.02.2014
comment
Просто используйте Mat::copyTo() с контурами как маска. - person Haris; 25.02.2014
comment
Харис, ты знаешь, как я могу это сделать? stackoverflow.com/ вопросы/61876457/ - person Tecnologia da Net; 18.05.2020