Обнаружение бифуркаций и конечных точек бинарного изображения с использованием OpenCV - PullRequest
0 голосов
/ 04 октября 2011

Я хочу обнаружить бифуркации и конечные точки в бинарном изображении, которое у меня есть. Изображение уже прорежено. Читал о том, как можно это сделать, но я не знаю, как я мог бы реализовать это в OpenCV. Все, что я знаю, это то, что я должен использовать окно 3х3 для сканирования всего изображения. Тогда это бифуркация, если сумма 0 пикселей в окне 3х3 меньше или равна 5, это конечная ветвь, если сумма 7 и 6 является непрерывной линией.

Прежде всего, я не знаю, как объявить окно 3x3 в OpenCV и как получить доступ к каждому из 9 блоков, которые составляют окно.

Во-вторых, как я могу затем переместить окно поверх изображения. Буду благодарен за помощь, пример кода также подойдет.

1 Ответ

0 голосов
/ 04 октября 2011

Чтобы получить окно матрицы 3х3, вы можете сделать следующее

Mat image = imread("image.png", 0);
// binarize it with cv::threshold or cv::adaptiveThreshold or something else.
Rect r(0, 0, 3, 3);
// this gets a 3x3 window starting with upper left of (0, 0) pixel
Mat windowImage(image, r);

Примечание. Области интереса, которые вы приобретаете, являются лишь ссылкой в ​​исходной матрице. Если вам нужна копия, вам нужно вызвать элемент clone () окна. Это укусило меня несколько раз: D

Чтобы получить доступ к пикселю в блоке, вы можете использовать функцию-член at () класса Mat. Вот так (при условии, что ваше изображение имеет тип CV_8UC1):

// block processing loops
for(int i = 0; i < windowImage.rows; i++)
{
    for(int j = 0; j < windowImage.cols; j++)
    {
        unsigned char val = windowImage.at<unsigned char>(i, j);
        // do pixel processing logic here...
    }
}

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

Чтобы переместить окно, вам нужно сместить туда, где находится интересующая область прямоугольника. Первые два параметра конструктора Rect берут верхние левые положения x и y для начала. Поэтому вам нужно разделить изображение на блоки.

const int BLOCK_SIZE = 3;
int rowBlocks = image.rows / BLOCK_SIZE;
int colBlocks = image.cols / BLOCK_SIZE;    

for(int i = 0; i < rowBlocks; i++)
{
    for(int j = 0; j < colBlocks; j++)
    {
        Mat block_ij(image, Rect(i, j, BLOCK_SIZE, BLOCK_SIZE));
        // block process here...
    }
}

Примечание: вам может потребоваться посмотреть, что функция copyMakeBorder добавляет рамку вокруг вашего изображения для случаев, когда размеры вашего изображения не делятся на 3.

...