A recent project used image recognition, has never touched OpenCV, after a variety of tutorials, and finally understand some.
The whole process is probably getting the image--image binary, grayscale (cvtcolor)--Image noise Reduction (gaussianblur)--Contour Recognition (cvfindcontours)--shape judgment.
Most of the tutorials are professional, various parameters analysis can not understand, after a variety of search finally understand.
Recognition Circle
OpenCV has a built-in method for recognizing circles: the Hough circle changes:
Houghcircles (edges, circles, cv_hough_gradient, 1.5, 10, 200, 100, 0, 0);
Parametric analysis:
Edges: Grayscale Image
Circles:std::vector<vec3f> circles; An array that stores the coordinate information for a circle
Cv_hough_gradient:hough transform mode, currently only supports Cv_hough_gradient, which is basically 21HT, described in [Yuen03]. This is the default.
1.5: The resolution of the accumulator image, 1 is the same as the obtained image, 1.5 is 1.5 times times
10: The minimum distance between circle and Circle, two center distance is considered as 1 circle if within range
200:100-200 Two parameter selection is enough.
100: Default 100, the lower the value the more inaccurate the recognition circle (the number of circles to identify the more likely to have an arc is recognized as a circle)
The last two parameters are the smallest and largest area of the recognition circle, respectively.
Rectangle Recognition
Rectangle recognition does not have a built-in method and requires your own handwriting.
The main method is to value two. The strength of the recognition is adjusted by the value of two.
Cvthreshold (Tgray, Gray, and cv_thresh_binary);
Parametric analysis:
SRC: Original Array (single channel, 8-bit of 32-bit floating-point number). DST: The output array must be the same as the SRC type, or 8-bit. Threshold: Threshold Max_value: Use the maximum value of cv_thresh_binary and CV_THRESH_BINARY_INV. Threshold_type: Threshold type threshold_type=cv_thresh_binary: If src (x, y) >threshold, DST (x, y) = Max_value; Otherwise, DST (x, y) = 0; THRESHOLD_TYPE=CV_THRESH_BINARY_INV: If SRC (x, y) >threshold,dst (x, y) = 0; Otherwise, DST (x, y) = Max_value. Threshold_type=cv_thresh_trunc: If SRC (x, y) >threshold,dst (x, y) = Max_value; Otherwise DST (x, y) = src (x, y). Threshold_type=cv_thresh_tozero: If SRC (x, y) >threshold,dst (x, y) = src (x, y); Otherwise DST (x, y) = 0. THRESHOLD_TYPE=CV_THRESH_TOZERO_INV: If SRC (x, y) >threshold,dst (x, y) = 0; Otherwise DST (x, y) = src (x, y). The effect diagram is as follows:
Two-value graph in rectangle recognition:
Circle Recognition:
Source:
#include <opencv2/opencv.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <winsock2. h> #include <iostream> #include <thread> #include <winsock2.h> #include <stdio.h> #include
<string> #include <windows.h> #pragma comment (lib, "Ws2_32.lib") #include <vector> using namespace CV; function function: Use vector to do cosα= two vector product/two vector modulus product to find two line segment angle/ /input: Segment 3 point coordinate pt1,pt2,pt0, last parameter is common point//output: Segment angle, Unit angle////////////////////////////////////////////////////////
Double Angle (cvpoint* pt1, cvpoint* pt2, cvpoint* 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; Double Angle_line = (dx1*dx2 + dy1 * dy2)/sqrt ((dx1*dx1 + dy1 * dy1) * (dx2*dx2 + dy2 * dy2) + 1e-10);//cosine return ACOs (a
ngle_line) * 180/3.141592653; }
////////////////////////////////////////function function: Using polygon detection, through constraints to find the rectangle//Input: IMG Original image//storage storage//Minarea,maxarea detection Rectangle min/Max area//minangle,maxangle detection rectangle Edge angle Range, unit angle//output: Rectangular sequence//////////////////////////////////////////////////// cvseq* findSquares4 (iplimage* img, cvmemstorage* storage, int minarea, int maxarea, int minangle, int maxan GLE, Int (&temp) [n]) {cvseq* contours;//edge int N = 6;
Threshold rating Cvsize Sz = cvsize (Img->width &-2, Img->height &-2); iplimage* timg = Cvcloneimage (IMG);//Copy once img iplimage* Gray = cvcreateimage (SZ, 8, 1); IMG Grayscale image iplimage* Pyr = Cvcreateimage (Cvsize (SZ.WIDTH/2, SZ.HEIGHT/2), 8, 3);
Pyramid Filter 3 Channel image Intermediate variable iplimage* Tgray = Cvcreateimage (SZ, 8, 1);;
cvseq* result;
Double S, t;
int SK = 0;
cvseq* squares = cvcreateseq (0, sizeof (CVSEQ), sizeof (Cvpoint), storage);
Cvsetimageroi (timg, cvrect (0, 0, sz.width, sz.height));
Pyramid Filter Cvpyrdown (timg, Pyr, 7);
Cvpyrup (Pyr, timg, 7); Look for a rectangle for (i) in 3 channelsNT C = 0; C < 3;
C + +)//3 channels are processed separately {cvsetimagecoi (timg, C + 1); Cvcopy (timg, Tgray, 0); The BGR channel is fed into Tgray for (int l = 0; l < N; l++) {//two value under different thresholds Cvthreshold (Tgray, Gray, Max, Cv_thre
Sh_binary);
Cvshowimage ("111", gray);
Cvfindcontours (gray, storage, &contours, sizeof (Cvcontour), Cv_retr_list, Cv_chain_approx_simple, cvpoint (0, 0)); while (contours) {//Polygon approximation result = cvapproxpoly (contours, sizeof (cvcontour), storage, Cv_poly_approx_
DP, Cvcontourperimeter (contours) *0.02, 0); If convex quadrilateral and area within range if (result->total = = 4 && fabs (Cvcontourarea (result, cv_whole_seq)) > Minarea && Amp
Fabs (Cvcontourarea (result, Cv_whole_seq)) < Maxarea && cvcheckcontourconvexity (Result)) {s = 0; Judge each edge for (int i = 0; i < 5; i++) {if (I >= 2) {//Angle T = Fabs (ang Le ((cvpoint*) Cvgetseqelem (result, i), (cvpoint*) Cvgetseqelem (result, I-2), (cvpoint*) Cvgetseqelem (result, i-1)); s = s > t?
S:t; }}//Here S is the right angle to determine the condition unit for the angle if (S > Minangle && s < maxangle) {for (int i = 0; i < 4;
i++) Cvseqpush (squares, (cvpoint*) Cvgetseqelem (result, i)); Cvrect rect = Cvboundingrect (contours, 1);
Gets the rectangle bounding box cvpoint p1; P1 = Cvpoint (rect.x + RECT.WIDTH/2, Rect.y + RECT.HEIGHT/2);
Rectangular Center coordinates std::cout << "X:" << p1.x << "Y:" << p1.y << Std::endl;
}} contours = contours->h_next;
}} std::cout << "The number of circles is" <<sk << Std::endl;
TEMP[26] = SK;
SK = 0;
} cvreleaseimage (&gray);
Cvreleaseimage (&pyr);
Cvreleaseimage (&tgray);
Cvreleaseimage (&TIMG);
return squares; }////////////////////////////////////////////////////////////////////function function: Draw all rectangles//Inputs: IMG Original image//squares rectangle sequence column//wndname window name//output: Mark Rectangle in Image/////////////////////void Drawsquares (iplimage* img, cvseq* squares, const char* wndname) {CvS
Eqreader reader;
iplimage* cpy = Cvcloneimage (IMG);
Cvpoint Pt[4];
int i;
Cvstartreadseq (squares, &reader, 0);
for (i = 0; i < squares->total; i + = 4) {cvpoint* rect = pt;
int count = 4;
memcpy (PT, Reader.ptr, squares->elem_size);
Cv_next_seq_elem (squares->elem_size, reader);
memcpy (pt + 1, reader.ptr, squares->elem_size);
Cv_next_seq_elem (squares->elem_size, reader);
memcpy (PT + 2, reader.ptr, squares->elem_size);
Cv_next_seq_elem (squares->elem_size, reader);
memcpy (PT + 3, reader.ptr, squares->elem_size);
Cv_next_seq_elem (squares->elem_size, reader);
Cvpolyline (cpy, &rect, &count, 1, 1, Cv_rgb (0,255,0), 3, CV_AA, 0); Cvpolyline (cpy, &rect, &count, 1, 1, Cv_rgb (rand () & 255, rand () & 255, rand () & 255), 1, CV_AA, 0);//
Color Rendering} cvshowimage ("cpy"); Cvreleaseimage (& cpy);
} void Sendmessageone () {//Open camera videocapture capture;
Capture.open (0); Mat edges;
Define the conversion grayscale if (!capture.isopened ()) Namedwindow ("Renderings", "cv_window_normal");
Const char* winn = "1111";
if (!capture.isopened ())//namedwindow (Winn, Cv_window_normal);
cvmemstorage* storage = 0;
cvmemstorage* storage = 0;
Storage = cvcreatememstorage (0);
while (1) {int y=0, j=0;
Mat frame;
Capture >> frame;
Iplimage img0 = frame;
Drawsquares (&img0, FindSquares4 (&img0, storage, N, a), Winn); Cvclearmemstorage (storage);
Empty storage Mat E = FRAME (range (1, +), range (1, 240));
Cvtcolor (frame, edges, cv_bgr2gray);
Gaussian filter Gaussianblur (edges, edges, Size (7, 7), 2, 2); Std::vector<vec3f> circles;//Stores the location information of each circle//Hough Circle Houghcircles (edges, circles, cv_hough_gradient, 1.5, 10,
100, 100, 0, 50);
for (size_t i = 0; i < circles.size (); i++) {Point Center (cvround (Circles[i][0]), Cvround (circles[i][1])); int radIUS = Cvround (circles[i][2]);
Std::cout << "Circle x is" << circles[i][0] << "Round y is" << circles[i][1] << std:: endl;
Draw Circle Outline Circle (frame, center, RADIUS, Scalar (155, 50, 255), 3, 8, 0); int R = frame.at<vec3b> (Cvround (circles[i][1]), Cvround (Circles[i][0])) [2];//r int G = frame.at<vec3b> (CvR Ound (Circles[i][1]), Cvround (Circles[i][0])) [1];//g int B = frame.at<vec3b> (Cvround (circles[i][1]), CvRound (
CIRCLES[I][0])) [0];//b int num = R + G + B;
Std::cout << "Center color is" << num << Std::endl;
} imshow ("Effect graph", frame);
Waitkey (30);
}} int main () {Std::thread *a = new Std::thread (sendmessageone);
A->join ();
return 0;
}
Reference Document: http://blog.csdn.net/qq_15947787/article/details/51085352