OpenCV соединяют тонкие линии - PullRequest
0 голосов
/ 29 марта 2020

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

Я хочу сделать так, чтобы линии были толщиной около 1 пикселя. Я играл с несколькими идеями, но без особого успеха. Я пробовал расширять erote и расширять как-то так:

int dsize = 5;
cv::Mat element = getStructuringElement(cv::MORPH_CROSS,
                          cv::Size(2*dsize + 1, 2*dsize + 1),
                          cv::Point( dsize, dsize ) );
cv::dilate( src, src, element );

Есть ли лучший способ, например, просто расширять и разрушать, чтобы делать именно то, что я хочу?

Ответы [ 2 ]

2 голосов
/ 30 марта 2020

Есть хотя бы пара решений, которые мы можем попробовать, но мне нужно больше информации о вашей проблеме. Например, вы пытаетесь закрыть (в) полный контур обнаруженного объекта? Какую «деградацию контура» вы готовы использовать для аппроксимации полностью замкнутого контура?

Вот первое и очень базовое c решение, при условии, что вам нужен контур 1 pixel ширины. Он включает dilating изображение N раз, а затем применяет thinning/skeletonize преобразование. (Эта функция является частью Extended Image Processing модуля OpenCV).

Давайте посмотрим код:

#include <opencv2/ximgproc.hpp>

//Read input image:
std::string imagePath = "C://opencvImages//lineImg.png";
cv::Mat imageInput= cv::imread( imagePath );

//Convert it to grayscale:
cv::Mat grayImg;
cv::cvtColor( imageInput, grayImg, cv::COLOR_BGR2GRAY );

//Get binary image via Otsu:
cv::threshold( grayImg, grayImg, 0, 255 , cv::THRESH_OTSU );

//Dilate the binary image with 5 iterations:
cv::Mat morphKernel = cv::getStructuringElement( cv::MORPH_RECT, cv::Size(3, 3) );
int morphIterations = 5;
cv::morphologyEx( grayImg, grayImg, cv::MORPH_DILATE, morphKernel, cv::Point(-1,-1), morphIterations );

Это изображение Dilated:

enter image description here

//Get the skeleton:
cv::Mat skel;
int algorithmType = 1;
cv::ximgproc::thinning( grayImg, skel, algorithmType ); 

Это изображение скелета . Линия была "прорежена" до ширины в 1 пиксель:

enter image description here

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

0 голосов
/ 30 марта 2020

Это вы рисуете линии на коврике? Кажется, проблему нужно взять в руки раньше. Вы должны нарисовать линию в большем cv :: mat, а затем изменить ее размер, чтобы сделать вашу линию толще. если вы хотите получить полную линию, не рисуйте каждую точку на карте, а линию между точками, чтобы получить линию от Брезенхэма.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...