边缘检测

记录下项目中的一点东西。

  1 //=======================================================================================
  2 // ParkingSystem.cpp
  3 // 
  4 //=======================================================================================
  5 // 5inch HDMI LCD 800x480
  6 // DPI = sqrt(800^2 + 480^2) / 5 = 186.6 像素/英寸
  7 // 屏幕宽 = 800 / 186.6 = 4.28 英寸 = 10.87 CM
  8 // 屏幕高 = 480 / 186.6 = 2.57 英寸 = 6.52  CM
  9 //
 10 /*
 11 
 12 x(图像中物体间距离)     X(实际中距离)
 13 --------------------  =  -------------
 14 f(焦距)                 D(相机到物体垂直距离)
 15 
 16 焦距 f 取: 10 cm
 17 相机到物体垂直距离 D 取: 50 cm
 18 
 19 */
 20 
 21 #include <opencv2opencv.hpp>
 22 #include <iostream>
 23 #include <string>
 24 #include <vector>
 25 #include <cmath>
 26 #include <windows.h>
 27 #include <process.h>
 28 //#include "RaspiCamCV.h"
 29 
 30 using namespace cv;
 31 using namespace std;
 32 
 33 const int CAMERA_WIDTH    = 400;
 34 const int CAMERA_HEIGHT    = 400;
 35 const int g_WIDTH = 400;
 36 const int g_HEIGHT = 400;
 37 
 38 // 像素阈值
 39 const int THRESHOLD = 255;
 40 // DPI
 41 const float LCD_DPI = 186.6;
 42 // 焦距(CM)
 43 const int CAMERA_FOCUS = 10;
 44 // 相机到物体垂直距离(CM)
 45 const int CAMERA_TO_OBJECT_DISTANCE = 50;
 46 
 47 // grobal variable
 48 static cv::Mat g_srcImage, g_srcGrayImage, g_edge, g_dstImage;
 49 static vector<Vec4i> g_allLines;
 50 static Point point1, point2;
 51 static Point VideoCenter(199, 199);
 52 
 53 // 推荐的高低阈值比在2:1到3:1之间
 54 const int CANNY_threshold1 = 30;
 55 const int CANNY_threshold2 = 80;
 56 
 57 const int HoughLines_threshold = 150;
 58 
 59 
 60 void Image_Processing();
 61 void DrawLine(Mat &img, Point start, Point end);
 62 void DrawHoughLines(Mat &img);
 63 float findDistanceBetweenPointsI(const CvPoint p1, const CvPoint p2);
 64 float CalcuteDistance(const CvPoint point1, const CvPoint point2, const CvPoint point3);
 65 
 66 
 67 //main
 68 //=======================================================================================
 69 int main()
 70 {
 71 
 72     VideoCapture videoCapture(0);
 73     videoCapture.set(CV_CAP_PROP_FRAME_WIDTH, CAMERA_WIDTH);
 74     videoCapture.set(CV_CAP_PROP_FRAME_HEIGHT, CAMERA_HEIGHT);
 75 
 76     cvNamedWindow("window1");
 77     cvMoveWindow("window1", 0, 40);
 78     cvNamedWindow("window2");
 79     cvMoveWindow("window2", g_WIDTH + 1, 40);
 80 
 81     while (1)
 82     {
 83         Mat cameraFrame;
 84         videoCapture >> cameraFrame;
 85         if (cameraFrame.empty()) 
 86         {
 87             cerr << "ERROR: Couldn't grab the next camera frame." << endl;
 88             exit(1);
 89         }
 90 
 91         // Get a copy of the camera frame that we can draw onto.
 92         Mat displayedFrame;
 93         cameraFrame.copyTo(displayedFrame);
 94         cameraFrame.copyTo(g_srcImage);
 95 
 96         Image_Processing();
 97         Mat finalImage(g_WIDTH,g_HEIGHT, CV_8UC3, Scalar(0, 0, 0));
 98         DrawHoughLines(finalImage);
 99 
100 
101         // Show the camera frame on the screen.
102         imshow("window1", displayedFrame);
103         // Show the final frame on the screen.
104         imshow("window2", finalImage);
105 
106 
107         // IMPORTANT: Wait for atleast 20 milliseconds, so that the image can be displayed on the screen!
108         // Also checks if a key was pressed in the GUI window. Note that it should be a "char" to support Linux.
109         char keypress = waitKey(20);  // This is needed if you want to see anything!
110         if (keypress == VK_ESCAPE) 
111         {   // Escape Key
112             // Quit the program!
113             break;
114         }
115 
116     }
117 
118     cvDestroyWindow("window1");
119     cvDestroyWindow("window2");
120     return 0;
121 }
122 
123 
124 // 图像预处理
125 void Image_Processing()
126 {
127     cvtColor(g_srcImage, g_srcImage, COLOR_BGR2GRAY);;
128     
129     equalizeHist(g_srcImage, g_srcGrayImage);
130 
131     // 先使用 3x3内核来降噪
132     blur(g_srcGrayImage, g_edge, Size(3, 3));
133     // 运行Canny算子,边缘检测
134     Canny(g_edge, g_edge, CANNY_threshold1, CANNY_threshold2, 3);
135 
136     // 霍夫线变换
137     HoughLinesP(g_edge, g_allLines, 1, CV_PI / 180, HoughLines_threshold, 50, 10);
138 
139 }
140 
141 // 画直线
142 void DrawLine(Mat &img, Point start, Point end)
143 {
144     int thickness = 1;
145     int lineType = 8;
146     // 红色,细
147     line(img,
148         start,
149         end,
150         Scalar(0, 0, 255),
151         thickness,
152         lineType);
153 }
154 
155 // 画霍夫线变换后的直线
156 void DrawHoughLines(Mat &img)
157 {
158     Vec4i L;
159     for (size_t i = 0; i < g_allLines.size(); i++)
160     {
161         L = g_allLines[i];
162         DrawLine(img, Point(L[0], L[1]), Point(L[2], L[3]));
163     }
164 }
165 
166 float findDistanceBetweenPointsI(const CvPoint p1, const CvPoint p2)
167 {
168     // Calc the pythagoras distance.
169     int dx = (p1.x - p2.x);
170     int dy = (p1.y - p2.y);
171     return sqrt((float)(dx * dx + dy * dy));
172 }
173 
174 // 计算 point3 到由 point1和point2构成的直线距离
175 float CalcuteDistance(const CvPoint point1, const CvPoint point2, const CvPoint point3)
176 {
177     float K, D;
178     if (point2.x == point1.x)
179     {
180         return fabs(float((point3.x - point1.x)));
181     }
182     else if (point2.y == point1.y)
183     {
184         return fabs(float((point3.y - point1.y)));
185     }
186     else
187     {
188         /*
189 
190         A*x + B*y + C = 0
191         d = | A*x0 + B*y0 + C | / sqrt(A^2 + B^2)
192 
193         K = (y2 - y1) / (x2 - x1)
194         K*x - y + y1 - K*x1 = 0
195 
196         */
197         K = (float(point2.y - point1.y) / float(point2.x - point1.x));
198         D = fabs(K*point3.x - point3.y + point1.y - K*point1.x) / sqrt(K*K + 1);
199         return D;
200     }
201 }
原文地址:https://www.cnblogs.com/ht-beyond/p/5222944.html