Исключение или пропуск контуров в углах изображения - PullRequest
0 голосов
/ 04 ноября 2019

У меня есть камера под стеклом с ИК-подсветкой для обнаружения объектов. Я могу найти контуры и нарисовать их, используя следующий код (я просто нашел несколько примеров в Интернете и изменил их по своему усмотрению, поэтому я вообще не мастер!).

using namespace cv;

cvtColor(mat, mat, COLOR_BGR2GRAY);
blur(mat, mat, Size(3,3));

erode(mat, mat, NULL, Point(-1,-1), 2);
dilate(mat, mat, NULL, Point(-1,-1), 2);
Canny(mat, mat, 100, 200);

auto contours = std::vector<std::vector<Point>>();
auto hierarchy = std::vector<Vec4i>();
findContours(mat, contours, hierarchy, CV_RETR_TREE,
             CV_CHAIN_APPROX_SIMPLE, Point(0, 0));

Mat drawing = Mat::zeros(mat.size(), CV_8UC3);
for( int i = 0; i< contours.size(); i++ ) {
    Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0,255),
                           rng.uniform(0,255));
    drawContours(drawing, contours, i, color, 2, 8, hierarchy, 0, Point());
}

putText(mat,
        (QString("Blobs: %1").arg(contours.size())).toStdString(),
        Point(25,175), cv::FONT_HERSHEY_PLAIN, 10, CV_RGB(0, 0, 255), 2);

Этот код приводит кхорошее нахождение контуров, которыми я вполне доволен. За исключением того факта, что мой ИК-свет как-то создает артефакты в углах и нижней части изображения.

enter image description here

Вы можете видеть, что я использовал gimp для выделенияобласти, которые я хочу игнорировать при поиске контуров. Под серым оттенком вы видите белые пиксели, которые мой исходный код распознает как контуры. Эти области проблематичны, и я хочу исключить их из поиска контура или рисования контура (в зависимости от того, что проще!)

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

Я думаю, что в контуре должны быть некоторые данные, которые говорят мне, где находятся пиксели, но я пока не могу понять это ...

1 Ответ

0 голосов
/ 04 ноября 2019

Самый простой способ - просто обрезать изображение. Области изображения называются областями интереса в OpenCV, что означает «Область интересов».

Итак, вы можете просто сказать:

cv::Mat image_roi = image(cv::Rect(x, y, w, h));

В основном это прямоугольная область с верхним левым краемугол на x,y, ширина w и высота h.

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

image(cv::Rect(x, y, w, h)).setTo(cv::Scalar(0, 0, 0));

Это устанавливает черный прямоугольный участок. Затем вам нужно определить 4 прямоугольных области на границах вашего изображения, которые вы хотите сделать темными.

Обратите внимание, что все вышеперечисленное основано на ручной настройке и некоторых экспериментах, и это будет работать при условии, что ваша системастатичным.

...