Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to select Side Window Filter-aided rectangle detection reasonably in OpenCV image processing

2025-02-23 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/01 Report--

This article introduces you how to reasonably choose Side Window Filter-assisted rectangular box detection in OpenCV image processing, the content is very detailed, interested friends can refer to, hope to be helpful to you.

1. Preface

What are you going to do today? The rectangle is detected by the traditional algorithm on a picture. To prevent you from getting bored, let's start with a set of comparative pictures.

The result map processed by the original image algorithm

This algorithm comes from https://stackoverflow.com/questions/8667818/opencv-c-obj-c-detecting-a-sheet-of-paper-square-detection, so let's understand it from the point of view of source code.

two。 The principle of the algorithm is to filter the original image. You can choose either the ordinary median filter or the Side Window Filter median filter, depending on whether you need to save more edges and corners in the image. Look for a rectangular region in each color channel of the image. This can be subdivided into: using different thresholds to obtain the corresponding binary image in the image corresponding to each color channel. After obtaining the binary image, the findContours algorithm is used to find the contour region. For each region, the approxPolyDP algorithm is used to approximate the contour to polygons. For the polygon approximated above, it is judged whether the number of vertices is 4, whether it is convex, and whether the cosin value of the angle between the adjacent edges is close to 0 (that is, the angle is 90 degrees). If it is satisfied that the polygon is rectangular, it is stored in the result. Draw the detected rectangular area in the result diagram. 3. Code implementation

The core code implementation of the above algorithm is given below.

Const double eps = 1e-7

/ / get the angle between pt0- > pt1 vector and pt0- > pt2 vector

Static double angle (Point pt1, Point pt2, Point pt0)

{

Double dx1 = pt1.x-pt0.x

Double dy1 = pt1.y-pt0.y

Double dx2 = pt2.x-pt0.x

Double dy2 = pt2.y-pt0.y

Return (dx1*dx2 + dy1*dy2) / sqrt ((dx1*dx1 + dy1*dy1) * (dx2*dx2 + dy2*dy2) + eps)

}

/ / find a rectangle

Static void findSquares (const Mat& image, vector& squares, int Nickel 5, int thresh=50)

{

/ / filtering can improve the performance of edge detection

Mat timg (image)

/ / ordinary median filtering

MedianBlur (image, timg, 9)

/ / median filtering of SideWindowFilter

/ / timg = MedianSideWindowFilter (image, 4)

Mat gray0 (timg.size (), CV_8U), gray

/ / Storage profile

Vector contours

/ / look for a rectangle in each color channel of the image

For (int c = 0; c

< 3; c++) { int ch[] = { c, 0 }; // 函数功能:mixChannels主要就是把输入的矩阵(或矩阵数组)的某些通道拆分复制给对应的输出矩阵(或矩阵数组)的某些通道中,其中的对应关系就由fromTo参数制定. // 接口:void mixChannels (const Mat* src , int nsrc , Mat* dst , int ndst , const int* fromTo , size_t npairs ); // src: 输入矩阵,可以为一个也可以为多个,但是矩阵必须有相同的大小和深度. // nsrc: 输入矩阵的个数. // dst: 输出矩阵,可以为一个也可以为多个,但是所有的矩阵必须事先分配空间(如用create),大小和深度须与输入矩阵等同. // ndst: 输出矩阵的个数 // fromTo:设置输入矩阵的通道对应输出矩阵的通道,规则如下:首先用数字标记输入矩阵的各个通道。输入矩阵个数可能多于一个并且每个矩阵的通道可能不一样, // 第一个输入矩阵的通道标记范围为:0 ~src[0].channels() - 1,第二个输入矩阵的通道标记范围为:src[0].channels() ~src[0].channels() + src[1].channels() - 1, // 以此类推;其次输出矩阵也用同样的规则标记,第一个输出矩阵的通道标记范围为:0 ~dst[0].channels() - 1,第二个输入矩阵的通道标记范围为:dst[0].channels() // ~dst[0].channels() + dst[1].channels() - 1, 以此类推;最后,数组fromTo的第一个元素即fromTo[0]应该填入输入矩阵的某个通道标记,而fromTo的第二个元素即 // fromTo[1]应该填入输出矩阵的某个通道标记,这样函数就会把输入矩阵的fromTo[0]通道里面的数据复制给输出矩阵的fromTo[1]通道。fromTo后面的元素也是这个 // 道理,总之就是一个输入矩阵的通道标记后面必须跟着个输出矩阵的通道标记. // npairs: 即参数fromTo中的有几组输入输出通道关系,其实就是参数fromTo的数组元素个数除以2. mixChannels(&timg, 1, &gray0, 1, ch, 1); // 尝试几个不同的阈值 for (int l = 0; l < N; l++) { // hack: use Canny instead of zero threshold level. // Canny helps to catch squares with gradient shading // 在级别为0的时候不使用阈值为0,而是使用Canny边缘检测算子 if (l == 0) { // void Canny( InputArray image, OutputArray edges, double threshold1, double threshold2, int apertureSize = 3, bool L2gradient = false); // 第一个参数:输入图像(八位的图像) // 第二个参数:输出的边缘图像 // 第三个参数:下限阈值,如果像素梯度低于下限阈值,则将像素不被认为边缘 // 第四个参数:上限阈值,如果像素梯度高于上限阈值,则将像素被认为是边缘(建议上限是下限的2倍或者3倍) // 第五个参数:为Sobel()运算提供内核大小,默认值为3 // 第六个参数:计算图像梯度幅值的标志,默认值为false Canny(gray0, gray, 5, thresh, 5); // 执行形态学膨胀操作 dilate(gray, gray, Mat(), Point(-1, -1)); } else { // 当l不等于0的时候,执行 tgray(x,y) = gray(x,y) < (l+1)*255/N ? 255 : 0 gray = gray0 >

= (l + 1) * 255 / N

}

/ / find outlines and store them all as lists

FindContours (gray, contours, RETR_LIST, CHAIN_APPROX_SIMPLE)

/ / Store a polygon (rectangle)

Vector approx

/ / Test each profile

For (size_t I = 0; I

< contours.size(); i++) { // 近似轮廓,精度与轮廓周长成正比,主要功能是把一个连续光滑曲线折线化,对图像轮廓点进行多边形拟合。 // 函数声明:void approxPolyDP(InputArray curve, OutputArray approxCurve, double epsilon, bool closed) // InputArray curve:一般是由图像的轮廓点组成的点集 // OutputArray approxCurve:表示输出的多边形点集 // double epsilon:主要表示输出的精度,就是两个轮廓点之间最大距离数,5,6,7,,8,,,,, // bool closed:表示输出的多边形是否封闭 // arcLength 计算图像轮廓的周长 approxPolyDP(Mat(contours[i]), approx, arcLength(Mat(contours[i]), true)*0.02, true); // 近似后,方形轮廓应具有4个顶点 // 相对较大的区域(以滤除嘈杂的轮廓)并且是凸集。 // 注意: 使用面积的绝对值,因为面积可以是正值或负值-根据轮廓方向 if (approx.size() == 4 && fabs(contourArea(Mat(approx))) >

1000 &

IsContourConvex (Mat (approx)

{

Double maxCosine = 0

For (int j = 2; j

< 5; j++) { // 找到相邻边之间的角度的最大余弦 double cosine = fabs(angle(approx[j % 4], approx[j - 2], approx[j - 1])); maxCosine = MAX(maxCosine, cosine); } // 如果所有角度的余弦都很小(所有角度均为90度),将顶点集合写入结果vector if (maxCosine < 0.3) squares.push_back(approx); } } } } } //在图像上画出方形 void drawSquares(Mat &image, const vector& squares) { for (size_t i = 0; i < squares.size(); i++) { const Point* p = &squares[i][0]; int n = (int)squares[i].size(); //不检测边界 if (p->

X > 3 & & p-> y > 3)

Polylines (image, & p, & n, 1, true, Scalar (0,255,0), 3, LINE_AA)

}

}

In the above code, it is implemented completely in accordance with the principle of the algorithm, which is easier to understand. When I was testing a picture, I found that applying Side Window Filter to this would sometimes produce better results, so I implemented a Side Window Filter for median filtering. For reasons of length, please check my github, address: https://github.com/BBuf/Image-processing-algorithm/blob/master/MedianSideWindowFilter.cpp. About SideWindowFilter, please see our article two days ago: [AI Mobile algorithm Optimization] 1, CVRR 2018 SideWindow Filtering paper interpretation and C++ implementation

4. The result of the ordinary median filter the original image of some signs after the rectangle detection (because there is a filtering operation, so the picture has changed, you can use temporary variables to save the original image, better)

In this example, the ordinary median filter is better, so there is no need to use the Side Window Filter median filter.

5. Comparing the results of ordinary median filter and Side Window Filter median filter, the detection rate of the second image using ordinary median filter is much higher than that of Side Window Filter median filter.

We can see that in the last picture, because of the use of Side Window Filter, it eliminates some noise and preserves the edges and corners, which makes the detection rate much higher, which also shows the effectiveness of Side Window Filter.

On how to reasonably choose Side Window Filter-assisted rectangle detection in OpenCV image processing is shared here, I hope the above content can be of some help to everyone and learn more knowledge. If you think the article is good, you can share it for more people to see.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report