使用 OpenCV 检测二值图像的分叉和端点

发布于 2024-12-08 04:17:49 字数 269 浏览 1 评论 0原文

我想检测我拥有的二值图像中的分叉和端点。图像已经变细了。一直在阅读如何做到这一点的方法,但我不知道如何在 OpenCV 中实现它。我所知道的是,我必须使用 3x3 窗口来扫描整个图像。如果 3x3 窗口上的 0 像素之和小于或等于 5,则这是一个分叉,如果总和为 7,则这是一个终止分支,并且如果6 是一条连续线。

首先,我不知道如何在 OpenCV 中声明一个 3x3 窗口以及如何访问组成该窗口的 9 个块中的每一个。

其次,我怎样才能将窗口移动到图像上。将感谢您的帮助,示例代码也可以。

I want to detect bifurcations and endpoints in a binary image that I have. The image has already been thinned. Been reading on ways of how one can possible do this, but I don't know how I could go about implementing it in OpenCV. All I know is that I have to use a 3x3 window to scan the whole image.Then this is a bifurcation if the sum of 0 pixels on the 3x3 window are less or equal 5, is a terminate branch if the sum is 7 and if is 6 is a continuous line.

First of how, I don't know how to declare a 3x3 window in OpenCV and how to access each of the 9 blocks that make up the window.

Secondly how can I then move the window over the image. Will be grateful for your help, a sample code will also do.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

花之痕靓丽 2024-12-15 04:17:49

为了获得矩阵的 3x3 窗口,您可以执行以下

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);

操作注意:您获取的感兴趣区域只是原始矩阵内的引用,如果您想要副本,则需要调用窗户。这让我咬了好几次: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 整除的情况下在图像周围添加边框。

In order to get a 3x3 window of a matrix you can do the following

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);

Note: That the region of interest you acquire is only a reference inside the original matrix if you want a copy you'll need to call the clone() member of the window. This has bit me a few times :D

To access a pixel within the block you can use the at() member function of the Mat class. Like this (assuming your image is of type 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...
    }
}

Also, note the at() member has a bit of overhead, so if you want fast look at using the data pointer to speed things up.

To move the window around, you need to shift where the rectangle region of interest is. The first two parameters of the Rect constructor take the upper-left x and y locations to start at. So you'll need to divide your image into blocks.

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...
    }
}

Note: you may need to look that the function copyMakeBorder to add a border around your image for the cases when your image dimensions are not divisible by 3.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文