2016-03-07 3 views
0

Я обрабатываю видеоизображения, и я хотел бы определить, содержит ли видео какие-либо пиксели определенного диапазона красного цвета. Это возможно?OpenCV: как я могу интерпретировать результаты inRange?

Вот код, я адаптируя из учебника:

#ifdef __cplusplus 
- (void)processImage:(Mat&)image; 
{ 
    cv::Mat orig_image = image.clone(); 
    cv::medianBlur(image, image, 3); 
    cv::Mat hsv_image; 
    cv::cvtColor(image, hsv_image, cv::COLOR_BGR2HSV); 
    cv::Mat lower_red_hue_range; 
    cv::Mat upper_red_hue_range; 
    cv::inRange(hsv_image, cv::Scalar(0, 100, 100), cv::Scalar(10, 255, 255), lower_red_hue_range); 
    cv::inRange(hsv_image, cv::Scalar(160, 100, 100), cv::Scalar(179, 255, 255), upper_red_hue_range); 
    // Interpret values here 
} 

Интерпретация значения

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

+0

Сначала вам нужно ИЛИ нижнюю и верхнюю маску. Затем вы можете 'countNonZero' посмотреть, нет ли нулевых пикселей (т. Е. Вы что-то нашли). Было бы лучше сначала применить морфологическую эрозию или открыть, чтобы удалить небольшие (возможно, шумные) капли или найти подключенные компоненты ('findContours',' connectedComponentsWithStats') и обрезать/искать по некоторым критериям – Miki

+0

Спасибо. Я знаю, что это хромает, но можете ли вы добавить пример кода? Это мой самый первый тестовый проект OpenCV, и я очень скоро знакомлюсь со всеми этими функциями и концепциями. – mm24

+0

Я отправил ответ. Это должно заставить вас начать. Если у вас есть более точные требования, добавьте их к своему вопросу, и я постараюсь сделать более точный ответ. – Miki

ответ

0

Прежде всего, необходимо ИЛИ нижней и верхней маски:

Mat mask = lower_red_hue_range | upper_red_hue_range; 

Тогда вы можете countNonZero, чтобы увидеть, если есть не ноль пикселей (т.е. вы нашли что-то).

int number_of_non_zero_pixels = countNonZero(mask); 

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

Mat kernel = getStructuringElement(MORPH_ELLIPSE, Size(3, 3)); 
morphologyEx(mask, mask, MORPH_OPEN, kernel); // or MORPH_ERODE 

или найти компоненты связности (findContours, connectedComponentsWithStats) и сливовый/Поиск по словам некоторые критерии:

vector<vector<Point>> contours 
findContours(mask.clone(), contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE); 

double threshold_on_area = 100.0; 
for(int i=0; i<contours.size(); ++i) 
{ 
    double area = countourArea(contours[i]); 
    if(area < threshold_on_area) 
    { 
     // don't consider this contour 
     continue; 
    } 
    else 
    { 
     // do something (e.g. drawing a bounding box around the contour) 
     Rect box = boundingRect(contours[i]); 
     rectangle(hsv_image, box, Scalar(0, 255, 255)); 
    } 
}