Цель: Я хочу обнаружить определенные области листовых изображений. Я нашел связанные с этим проблемы, близкие к которым этот сегментный объект (лист), который находится на белой бумаге, используя обработку изображений (удаление листа с белого фона), но мой выходит за его пределы, он нацелен на извлечение/сегмент больной области листа.
Проблема: как точно сегментировать и извлекать больные участки листа на изображении.
Моя попытка:
1. inRange() Функция OpenCV -Threshold зеленого цвета, так что я не буду делать несколько значений inRange для незеленых областей (коричневый, серый и т.д.), И я буду надежно удалить зеленый цвет; Я применил Gaussian blur, преобразованный из RGB в HSV перед сегментацией
Ссылка на файлы image1, входные данные image2 и результаты:
Image1: Результат: Зеленый был сегментирован (подумал не совсем точно), но я до сих пор не знаю, как извлечь незеленые зоны (в качестве следующего шага)
Image2: Результат: Темные маленькие круги были включены/считаются зелеными, что, предположительно, не должно
Я новичок в OpenCV (а также C++), и я прочитал несколько методов (например, методы кластеризации fuzzy-c и k-средства и т.д.) Для сегментации, но я не могу решить, какой метод сегментации использовать для моих изображений. Я также узнал из прочитанных статей, что нет такой техники, как универсальная техника сегментации, которая может применяться ко всем изображениям.
Таким образом, я хотел бы знать, какой метод (метод кластеризации? "Основан на" гистограмме? "И т.д.), Или процесс лучше всего применять для изображений, которые у меня есть, для точного сегментации изображений.
Большое спасибо.
Просто попробуйте выполнить шаги ниже.
Create Mask Image: - Сначала вам нужно создать изображение маски для листа, вам нужно сделать пороговое значение, найти контур (наибольший), рисовать контур (с заполнением) и т.д.... также для устранения эффекта края вам нужно подобрать маску, что даст лучший результат.
Нижеследующие фрагменты кода будут делать вышеуказанные
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 и т.д. Также в приведенном выше алгоритме считают, что ваш фон всегда белый, а для другого фона вам нужно изменить шаги для создания изображения маски.
Надеюсь, что эти полезные...