2

Я работаю над небольшим проектом OpenCV до обнаруживает линии определенного цвета с камеры мобильного телефона.OpenCV: как определить линии определенного цвета?

Короче хотелось бы:

  1. Преобразование входного изображения в изображение определенного цвета (например, красный с определенного верхнего и нижнего диапазона)
  2. Применить преобразование Хафа линии к полученному изображению, так что он обнаруживает только линии этого конкретного цвета
  3. SUPERIMPOSE на исходном изображении обнаружены линии

Те функции, которые я хотел бы использовать, но не Цюй Я уверен, как заполнить недостающие бит.

Это функция processImage вызывается из смартфона приложение при обработке изображений из экземпляра CvVideoCamera

- (void)processImage:(Mat&)image; 
{ 
cv::Mat orig_image = image.clone(); 

cv::Mat red_image = ?? 

// Apply houghes transformation to detect lines between a minimum length and a maximum length (I was thinking of using the CV_HOUGH_PROBABILISTIC method..) 
// Comment.. see below.. 

Я не могу понять documentation here как С ++ метод подписи не имеет поля метода

vector<Vec2f> lines; 

Из официальной документации:

C++: недействительных HoughLines (InputArray изображения, OutputArray линии, двойной Rho, двойной тета, внутр порог, двойной SRn = 0, двойная STN = 0)

HoughLines(dst, lines, 1, CV_PI/180, 100, 0, 0); 

Взятые из образцов кода, не поняли должным образом, как это работает ..

(например, Каково использование тета? Как давать разный угол отражать в обнаружении линии?)

for(size_t i = 0; i < lines.size(); i++) 
{ 

Здесь я должен рассматривать только строки выше определенного размера нет .. (не знаю, как)

} 

Здесь я должен затем добавить результирующие строки к исходному изображению (не знаю, как), чтобы они могли отображаться на экране.

Любая помощь была бы принята с благодарностью.

+0

Для получения размера линий используйте вероятностное преобразование Hough. Только линии над определенной длиной будут обнаружены им. – FadedCoder

+0

Можете ли вы разместить (пару) изображений? Это будет проще и понятнее объяснить. – Miki

+0

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

ответ

5

Вы можете использовать цветовое пространство HSV для извлечения информации цветового тона.

Вот код с комментариями, если есть какие-либо вопросы, не стесняйтесь спросить:

int main(int argc, char* argv[]) 
{ 
    cv::Mat input = cv::imread("C:/StackOverflow/Input/coloredLines.png"); 

    // convert to HSV color space 
    cv::Mat hsvImage; 
    cv::cvtColor(input, hsvImage, CV_BGR2HSV); 

    // split the channels 
    std::vector<cv::Mat> hsvChannels; 
    cv::split(hsvImage, hsvChannels); 

    // hue channels tells you the color tone, if saturation and value aren't too low. 

    // red color is a special case, because the hue space is circular and red is exactly at the beginning/end of the circle. 
    // in literature, hue space goes from 0 to 360 degrees, but OpenCV rescales the range to 0 up to 180, because 360 does not fit in a single byte. Alternatively there is another mode where 0..360 is rescaled to 0..255 but this isn't as common. 
    int hueValue = 0; // red color 
    int hueRange = 15; // how much difference from the desired color we want to include to the result If you increase this value, for example a red color would detect some orange values, too. 

    int minSaturation = 50; // I'm not sure which value is good here... 
    int minValue = 50; // not sure whether 50 is a good min value here... 

    cv::Mat hueImage = hsvChannels[0]; // [hue, saturation, value] 

    // is the color within the lower hue range? 
    cv::Mat hueMask; 
    cv::inRange(hueImage, hueValue - hueRange, hueValue + hueRange, hueMask); 

    // if the desired color is near the border of the hue space, check the other side too: 
    // TODO: this won't work if "hueValue + hueRange > 180" - maybe use two different if-cases instead... with int lowerHueValue = hueValue - 180 
    if (hueValue - hueRange < 0 || hueValue + hueRange > 180) 
    { 
     cv::Mat hueMaskUpper; 
     int upperHueValue = hueValue + 180; // in reality this would be + 360 instead 
     cv::inRange(hueImage, upperHueValue - hueRange, upperHueValue + hueRange, hueMaskUpper); 

     // add this mask to the other one 
     hueMask = hueMask | hueMaskUpper; 
    } 

    // now we have to filter out all the pixels where saturation and value do not fit the limits: 
    cv::Mat saturationMask = hsvChannels[1] > minSaturation; 
    cv::Mat valueMask = hsvChannels[2] > minValue; 

    hueMask = (hueMask & saturationMask) & valueMask; 

    cv::imshow("desired color", hueMask); 

    // now perform the line detection 
    std::vector<cv::Vec4i> lines; 
    cv::HoughLinesP(hueMask, lines, 1, CV_PI/360, 50, 50, 10); 

    // draw the result as big green lines: 
    for (unsigned int i = 0; i < lines.size(); ++i) 
    { 
     cv::line(input, cv::Point(lines[i][0], lines[i][1]), cv::Point(lines[i][2], lines[i][3]), cv::Scalar(0, 255, 0), 5); 
    } 


    cv::imwrite("C:/StackOverflow/Output/coloredLines_mask.png", hueMask); 
    cv::imwrite("C:/StackOverflow/Output/coloredLines_detection.png", input); 

    cv::imshow("input", input); 
    cv::waitKey(0); 
    return 0; 
} 

использованием этого входного изображения:

enter image description here

извлечет этот «красный» цвет (отрегулировать hueValue и hueRange для определения различных цветов):

enter image description here

и HoughLinesP обнаруживает эти строки из маски (должен работать с HoughLines аналогично):

enter image description here

Вот еще один набор изображений с не-линий тоже ...

enter image description here

enter image description here

enter image description here

О ваших различных вопросов:

  1. Есть две функции HoughLines и HoughLinesP. HoughLines не извлекает длину строки, но вы можете вычислить ее в постобработке, снова проверив, какие пиксели краевой маски (вход HoughLines) соответствуют выделенной строке.

  2. параметры:

    изображение - края изображения (должно быть ясно?) линии - линии, данные по углу и положению, не имеющей длины или СТГ. они интерпретируются бесконечно долго. rho - разрешение аккумулятора. Чем больше, тем более надежным в случае слегка искаженных линий оно должно быть, но тем менее точным в позиции/углах выделенных линий. порог - чем меньше ложных срабатываний, тем больше вы можете пропустить некоторые линии. theta - разрешение по углу: чем меньше, тем больше различий между линиями (в зависимости от ориентации). Если ориентация вашей линии не подходит для шагов угла, линия не может быть обнаружена. Например, если вы CV_PI/180 обнаружите в разрешении , если ваша линия имеет ориентацию 0.5° (например, 33.5°), она может быть пропущена.

Я не так уверен, что очень всех параметров, может быть, вы будете смотреть на литературу об обнаружении HOUGH линии, или кто-то может добавить некоторые намеки здесь.

Если вы вместо того, чтобы использовать cv::HoughLinesP, сегменты линии с указанием времени начала и конечной точкой будет обнаружено, что легче интерпретировать, и вы можете вычислить длину строки из cv::norm(cv::Point(lines[i][0], lines[i][1]) - cv::Point(lines[i][2], lines[i][3]))

+0

спасибо! Я собираюсь попробовать ваш код сейчас .. как я могу показать изображения на камере? Я использую функцию «- (void) processImage: (Mat &) image» для обработки изображения входного кадра .. хотел бы наложить обнаруженные изображения на него. – mm24

+0

просто переименуйте 'input' в мой код в' orig_image' и убедитесь, что 'orig_image' находится в формате BGR. – Micka

+0

Я добавил некоторую информацию о параметрах – Micka

1

Я не буду показывать код, но шаги с некоторыми трюками.

Предположим, что вы хотите обнаружить дорожные полосы (которые являются линиями белого или светло-желтого цвета и имеют определенные свойства).

Исходное изображение (добавить некоторые дополнительные линии шуметь)

enter image description here

Шаг 1: Удалите части изображения, которые не должны быть использованы, за исключением использования процессора (простой, но полезно)

enter image description here

Шаг 2: Преобразование в серое изображение

enter image description here

Шаг 3: порог

Использование порогового значения в соответствии с цветом вашей линии, цвет станет белым и другие станут черными

enter image description here

Шаг 4: Использование контуров для определения границ объектов

enter image description here

Шаг 5: Использование Fitline с Контурами в предыдущей стадии, ввод вернуть уравнение линий

Fitline возвращается (x0, y0) и вектор v = (а, б)

enter image description here

Шаг 6: с уравнениями линий вы можете сделать в любой строке вы хотите

enter image description here

Смежные вопросы