Нужно только одно ребро в алгоритме Canny edge

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

введите здесь описание изображения

Вот код:

bool CannyEdgeDetection(DataStructure& col)
{

Mat src, src_gray;
Mat dst, detected_edges, fin;
int WhiteCount = 0, BCount = 0;

char  szFil1[32] = "ocv.bmp";
char  szFil2[32] = "dst.bmp";
src = imread(szFil1);
dst = imread(szFil1);
blur( src_gray, detected_edges, Size(3,3) );
Canny( src, dst, 100, 200, 3 );
imwrite(szFil2, dst );

IplImage* img = cvLoadImage(szFil2);
int height    = img->height;
int width     = img->width;
int step      = img->widthStep;
int channels  = img->nChannels;
uchar * datau      = (uchar *)img->imageData;

for(int i=0;i<height;i++){
for(int j=0;j<width;j++){
for(int k=0;k<channels;k++){
datau[i*step+j*channels+k] = 255 - datau[i*step+j*channels+k];   
if (datau[i*step+j*channels+k]==0){
WhiteCount++;
col.pixel_col [i][j] = 2;
}
else{BCount++;
col.pixel_col[i][j] = 0;
}
}
}
}

cvSaveImage("img.bmp" ,img);

return 0;

}

Это не оригинальное изображение, но похожее:

введите здесь описание изображения

Какую часть мне закомментировать, чтобы иметь возможность читать черные изображения на белом фоне? или любое цветное изображение?

bool done;
do
{
  cv::morphologyEx(img, temp, cv::MORPH_OPEN, element);
  cv::bitwise_not(temp, temp);
  cv::bitwise_and(img, temp, temp);
  cv::bitwise_or(skel, temp, skel);
  cv::erode(img, img, element);

  double max;
  cv::minMaxLoc(img, 0, &max);
  done = (max == 0);
} while (!done);

person Gambit King    schedule 15.07.2012    source источник
comment
что ты уже испробовал? Можете ли вы опубликовать код? Или хотя бы входное изображение?   -  person dom    schedule 15.07.2012
comment
можешь скинуть ссылку на исходное изображение? Может быть, другие люди могут предоставить лучшие методы.   -  person Abid Rahman K    schedule 15.07.2012
comment
Самый простой способ сделать это - изменить размер изображения - сделать его достаточно маленьким, чтобы края были 1-2 пикселя. У вас будут как 1-пиксельные тонкие края, так и мгновенный прирост производительности.   -  person Sam    schedule 16.07.2012


Ответы (1)


Этот процесс называется skeletonization или thinning. Вы можете погуглить для этого.

Вот simple method for skeletonization: скелетонизация OpenCV в C#

Ниже приведен output, который я получил, когда применил описанный выше метод к вашему изображению (Изображение инвертировано перед скелетированием, потому что описанный выше метод работает для white images in black background, как раз в противоположном случае вашего входного изображения).

введите здесь описание изображения

person Abid Rahman K    schedule 15.07.2012
comment
Это выглядит действительно полезно, почему скелетонизация не предпочтительнее хитрости при обработке изображений (я предполагаю это, потому что вообще не слышал об этом) - person Gambit King; 15.07.2012
comment
Я не уверен в этом, но обычно используется хитрое обнаружение краев, а также скелетонизация все еще является развивающимся подходом, изо дня в день готовится больше методов (подход в моем ответе не так хорош). Во всяком случае, я еще не использовал скелетонизацию. - person Abid Rahman K; 15.07.2012
comment
это поразительно! но будет ли это работать, если вы не знаете цвет изображения или фона? - person Gambit King; 15.07.2012
comment
Я не уверен в этом. Может быть проверка количества белых и черных пикселей перед истончением и решение, инвертировать или нет, может работать, поскольку обычно фон имеет большую площадь, чем передний план. - person Abid Rahman K; 15.07.2012
comment
у меня тоже работает.. но я не хочу инвертировать. что я должен закомментировать (не, и, или)? - person Gambit King; 15.07.2012
comment
Если у вас это работает, зачем вам комментировать любую строку? Я не понимаю вашего вопроса. - person Abid Rahman K; 15.07.2012
comment
потому что я инвертировал изображение в краске, а затем применил алгоритм, иначе это не сработало бы - person Gambit King; 15.07.2012
comment
вам не нужно инвертировать изображение так. Вы можете использовать функцию cv2.bitwise_not(), чтобы программно инвертировать изображение. - person Abid Rahman K; 15.07.2012
comment
я разместил код выше, с функцией bitwise_not он не производит никакого вывода, но когда я инвертирую изображение в краске, а затем запускаю программу, она работает - person Gambit King; 15.07.2012
comment
Не там, вы должны инвертировать изображение в начале полного кода, сразу после загрузки изображения. pastebin.com/e91gX57t - person Abid Rahman K; 15.07.2012