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 use C++ OpenCV to restore affine features from projected images

2025-03-31 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

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

How to use C++ OpenCV to restore affine features from projected images? for this problem, this article introduces the corresponding analysis and solution in detail, hoping to help more partners who want to solve this problem to find a more simple and feasible method.

Principle

There are all kinds of distortions in the pictures we take through the camera, among which the projection distortion makes the original parallel lines no longer parallel, which will have the same effect as the size of the photos. There are many ways to correct this distortion in the book. Here is one of them.

We can split the projection transformation into three parts: similarity transformation, affine transformation and projection transformation, as shown in the following figure

Similarity transformation and affine transformation will not change infinite line, only projection transformation will change. Therefore, as long as we find this line in the distorted image, we can restore the affine characteristics of the image (equivalent to reverse projection transformation). To determine the location of the line, you need to know at least two points on the line. We know that the intersection of all parallel lines is on the infinite line, so we only need to find two pairs of parallel lines on the image (originally parallel, but no longer parallel on the image), find the corresponding two intersection points, and we can find the infinite line, as shown in the following figure

Furthermore, the affine characteristics of the image can be restored.

Realization idea

First of all, our distorted image is shown below.

Using the formula:

L = x1 × x2

The homogeneous coordinates of the line l of the two points can be obtained from the homogeneous coordinates of x1 and x2. In the figure, we find two pairs of parallel lines L1, L2 and L3, L4, as shown below.

Using the formula:

X = L1 × L2

The intersection points A12 and A34 of two pairs of parallel lines can be obtained from the homogeneous coordinates of L1, L2 and L3, L4 respectively, and the straight line A12A34 is the infinite line we are looking for. Assuming that the homogeneous coordinate of the line is (L1MaginL2), then through the matrix:

H = ((1jin0re0), (0mem1re0), (l1rect L2meml3))

It is possible to transform a straight line (L1MagneL2MagneL3) into a straight line (0Magne0Phone1), that is, to restore the straight line to infinite line. By the same token, we can also use the H matrix, through the formula:

X = Hx'

Restore projection distortion.

Main code

The code needs to be run twice in total

The main function run for the first time:

Int main () {Mat src = imread ("distortion.jpg", IMREAD_GRAYSCALE); IplImage * src1 = cvLoadImage ("distortion.jpg"); / / the first step is to obtain the coordinates of a point in the picture through the mouse, and comment out Rectify (points_3d, src, src1) when you run the first step. Write the acquired eight points into the / / points_3d [8] coordinate array, because it is homogeneous, x3 = 1 GetMouse (src1) / input 8 key points on the distortion map Point3d points_3d [8] = {Point3d (99,147,1), Point3d (210,93,1), Point3d (144,184,1), Point3d (261,122,1), Point3d (144,184,1), Point3d (99,147,1), Point3d (261,122,1), Point3d (210,93,1)} / / the second step is to correct the image, comment out GetMouse (src1) when running this step; uncomment Rectify (points_3d, src, src1); / / Rectify (points_3d, src, src1); imshow ("yuantu", src); waitKey (0);}

Other functions:

Void on_mouse (int event, int x, int y, int flags, void* ustc) {CvFont font; cvInitFont (& font, CV_FONT_HERSHEY_SIMPLEX, 0.5,0.5,0,1, CV_AA); if (event = = CV_EVENT_LBUTTONDOWN) {CvPoint pt = cvPoint (x, y); char temp [16]; sprintf (temp, "(% d)", pt.x, pt.y) CvPutText (src, temp, pt, & font, cvScalar (255,255,255,0); cvCircle (src, pt, 2, cvScalar (255,0,0,0), CV_FILLED, CV_AA, 0); cvShowImage ("src", src);} void GetMouse (IplImage * img) {src = img; cvNamedWindow ("src", 1); cvSetMouseCallback ("src", on_mouse, 0); cvShowImage ("src", src) WaitKey (0);}

Click anywhere in the pop-up picture to get the image coordinates of the change point (x1Powerx2), as shown in the following figure:

I selected four points a, b, c and d, among which:

Ab / / cd ac / / bd

Fill the coordinates of these four points into the points_3d [8] coordinate array in the order of a, b, c, d, c, a, d, b, and the first run ends.

The main function of the second run:

Int main () {Mat src = imread ("distortion.jpg", IMREAD_GRAYSCALE); IplImage * src1 = cvLoadImage ("distortion.jpg"); / / the first step is to obtain the coordinates of a point in the picture through the mouse, and comment out Rectify (points_3d, src, src1) when you run the first step. Write the acquired eight points into the / / points_3d [8] matrix, because they are homogeneous coordinates, x3 = 1 / / GetMouse (src1) / input 8 key points on the distortion map Point3d points_3d [8] = {Point3d (99,147,1), Point3d (210,93,1), Point3d (144,184,1), Point3d (261,122,1), Point3d (144,184,1), Point3d (99,147,1), Point3d (261,122,1), Point3d (210,93,1)} / / the second step is to correct the image, comment out GetMouse (src1) when running this step; uncomment Rectify (points_3d, src, src1); Rectify (points_3d, src, src1); imshow ("yuantu", src); waitKey (0);}

Correction function:

Void Rectify (Point3d* points, Mat src, IplImage* img) {/ / get 4 connections by entering 8 points vector lines; int num_lines = 4; for (int I = 0; I)

< num_lines; i++) { //获取两点连线 GetLineFromPoints(points[2 * i], points[2 * i + 1], lines); } //分别求取两个交点 vector intersect_points; int num_intersect_points = 2; for (int i = 0; i < num_intersect_points; i++) { //计算交点 GetIntersectPoint(lines[2 * i], lines[2 * i + 1], intersect_points); } //通过两个交点连线求消失线 vector vanishing_line; GetLineFromPoints(intersect_points[0], intersect_points[1], vanishing_line); //恢复矩阵 float H[3][3] = {{1, 0, 0}, {0, 1, 0}, {vanishing_line[0][0], vanishing_line[0][1], vanishing_line[0][2]}}; Mat image = Mat::zeros(src.rows, src.cols, CV_8UC1); GetRectifingImage(vanishing_line[0], src, image); int i = 0;}void GetLineFromPoints(Point3d point1, Point3d point2, vector &lines){ vector line; //定义直线的三个齐次坐标 float l1 = 0; float l2 = 0; float l3 = 0; l1 = (point1.y * point2.z - point1.z * point2.y); l2 = (point1.z * point2.x - point1.x * point2.z); l3 = (point1.x * point2.y - point1.y * point2.x); //归一化 l1 = l1 / l3; l2 = l2 / l3; l3 = 1; line.push_back(l1); line.push_back(l2); line.push_back(l3); lines.push_back(line);}void GetIntersectPoint(vector line1, vector line2, vector &intersect_points){ Point3f intersect_point; //定义交点的三个齐次坐标 float x1 = 0; float x2 = 0; float x3 = 0; x1 = (line1[1] * line2[2] - line1[2] * line2[1]); x2 = (line1[2] * line2[0] - line1[0] * line2[2]); x3 = (line1[0] * line2[1] - line1[1] * line2[0]); //归一化 x1 = x1 / x3; x2 = x2 / x3; x3 = 1; intersect_point.x = x1; intersect_point.y = x2; intersect_point.z = x3; intersect_points.push_back(intersect_point);}int Round(float x){ return (x >

0.0)? Floor (x + 0.5): ceil (x-0.5);} void GetRectifingImage (vector line, Mat src, Mat dst) {Size size_src = src.size (); for (int I = 0; I)

< size_src.height; i++) { for (int j = 0; j < size_src.width; j++) { float x3 = line[0] * j + line[1] * i + line[2] * 1; int x1 = Round(j / x3); int x2 = Round(i / x3); if (x1 < size_src.width && x1 >

= 0 & & x2

< size_src.height && x2 >

= 0) {dst.at (x2, x1) = src.at (I, j);} imshow ("src", src); imshow ("dst", dst); waitKey (0);}

The running result is as follows:

The correction effect is related to the selection of points, because the point clicked by the mouse is not necessarily the point we really want, so it is recommended that the distance between the two points in a straight line should be as large as possible.

This is the answer to the question on how to use C++ OpenCV to restore affine features from projected images. I hope the above content can be of some help to you. If you still have a lot of doubts to be solved, you can follow the industry information channel for more related knowledge.

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

Development

Wechat

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

12
Report