Draw the clock with OpenCV and synchronize the system time dynamically



The process is roughly divided into two steps: the first step is to draw the clock; the second step is to synchronize the system time. The first step is related to opencv, and the second step is not well understood, so I don't make too many records.

A simple clock is a combination of line segments and circles. Including the outermost circle, 60 tick marks (12 of which are hourly tick marks) and three long line segments for the hour hand, minute hand and second hand.

The easiest way to draw a circle is to create a picture with the same length and width, take the center of the picture as the center, and draw a circle with half the length and width of the picture as the radius.

It is relatively troublesome to draw line segments, because a total of 60+12+3=75 line segments need to be drawn. The line drawing function line() of opencv needs to know the starting point of the line segment, and the starting points of the 75 straight lines we need to draw are different, we need to calculate them one by one. If our circle is drawn with the origin of our mathematical Cartesian coordinate system as the center and r as the radius, it is probably as follows:

 

Given the angle α, we can easily calculate the coordinates of point P:

x = r * cos(α)

y = r * sin(α)

But we know that the coordinate origin of the image in opencv is in the upper left corner, then we can change the lower coordinate system and get the following formula:

x = r + r * cos( α)

y = r + r * sin(α)

One minute and 60 seconds, the second hand scale is to divide the outer circle into 60 equal parts, and the angle between each two scales is 6 degrees. In the same way, the whole point scale is to divide the circle into 12 equal parts, and the included angle is 30 degrees.

We can calculate the coordinates of the starting point of each tick mark by using two circles, one large and one small, with similar radii, and then we can use line() to draw them. The same is true for the whole point scale.

After drawing the tick mark, obtain the system time, and then draw the hour, minute, and second hands in real time according to the time. I don't know much about this part, so I won't say more. The code is as follows:



#include

 

  

#include "opencv2/highgui/highgui.hpp"

#include "opencv2/imgproc/imgproc_c.h"

#include "opencv2/imgproc/imgproc.hpp"

#include

  

     #include

   

      #include

    

       //#include

     

        #include

      

         #include

       

          using namespace std; using namespace cv; int main() { Mat clk(640, 640, CV_8UC3,Scalar(180,120,50)); //Mat to store clock image Mat back_up(640, 640, CV_8UC3, Scalar(180, 120, 50)); //Mat to store backup image Point cent(clk.rows/2, clk.cols/2); Point perim(clk.cols/2, 0); int rad = clk.cols / 2; float sec_angle = 270; float min_angle = 330; float hour_angle = 210; //画秒针刻度 vector

        

           pt1,pt2; for (int i = 0; i < 60; i++) { int x1 = cent.x + rad*cos(i * 6 * CV_PI / 180.0); int y1 = cent.y + rad*sin(i * 6 * CV_PI / 180.0); pt1.push_back(Point(x1, y1)); int x2 = cent.x + (rad - 20)*cos(i * 6 * CV_PI / 180.0); int y2 = cent.y + (rad - 20)*sin(i * 6 * CV_PI / 180.0); pt2.push_back(Point(x2, y2)); line(clk, pt1[i], pt2[i], Scalar(0, 255, 0, 0), 1.5, CV_AA, 0); } //画整点刻度 vector

         

            pt3,pt4; for (int i = 0; i < 12; i++) { int x3 = cent.x + (rad - 40)*cos(i * 30 * CV_PI / 180.0); int http://www. cppentry.com Programming Development Programmer's Introduction y3 = cent.y + (rad - 40)*sin(i * 30 * CV_PI / 180.0); pt3.push_back(Point(x3, y3)); line(clk, pt1[( i*5)], pt3[i], Scalar(0, 255, 0, 0), 5, CV_AA, 0); } //Draw the outermost circle and the three-pin connection point at the center circle(clk, cent, rad, Scalar(50, 50, 255, 0), 6, CV_AA, 0); //Dreaw outercircle of clock circle(clk, cent, 2, Scalar(0, 255, 0, 0), 5, CV_AA, 0 ); //Draw inner circle back_up = clk.clone(); // Clone to backup image time_t rawtime; struct tm * timeinfo; float second; float minute; float hour; float millisec; struct timeb tmb; while (1){ //Get local time ftime(&tmb); rawtime = tmb.time; timeinfo = localtime (&rawtime); second = timeinfo->tm_sec; minute = timeinfo->tm_min; hour = timeinfo->tm_hour ;millisec = tmb.millitm; second = second + millisec / 1000; sec_angle = (second * 6) + 270; //Convert second to angle minute = minute + second / 60; min_angle = minute * 6 + 270; //Conver minute to angle if (hour>12)hour = hour - 12; hour_angle = (hour * 30) + (minute*.5) + 270; //Conver hour to angle if (sec_angle>360)sec_angle = sec_angle - 360; if (min_angle>360)min_angle = min_angle - 360; if (hour_angle>360)hour_angle = hour_angle - 360; //画秒针 perim.x = (int)cvRound(cent.x + (rad - 5) * cos(sec_angle * CV_PI / 180.0)); perim.y = (int)cvRound(cent.y + (rad - 5) * sin(sec_angle * CV_PI / 180.0)); line(clk, cent, perim, Scalar(0, 255, 255, 0), 1.5, CV_AA, 0); //画分针 perim.x = (int)cvRound(cent.x + (rad - 30) * cos(min_angle * CV_PI / 180.0)); perim.y = (int)cvRound(cent.y + (rad - 30) * sin(min_angle * CV_PI / 180.0));line(clk, cent, perim, Scalar(0, 255, 255, 0), 4, CV_AA, 0); // draw the hour hand perim.x = (int)cvRound(cent.x + (rad - 100) * cos (hour_angle * CV_PI / 180.0)); perim.y = (int)cvRound(cent.y + (rad - 100) * sin(hour_angle * CV_PI / 180.0)); line(clk, cent, perim, Scalar(0, 255, 255, 0), 12, CV_AA, 0); imshow("Clock", clk); //Show result in a window clk.setTo(0); // set clk image to zero for next drawing clk = back_up.clone(); // Clone the previously drawned markings from back-up image char c = waitKey(999); // Here if the parameter is 10, you will see that the second hand rotates continuously; if it is 1000, the effect is the second hand jumping second by second if (c == 27)break; } return 0; }255, 255, 0), 12, CV_AA, 0); imshow("Clock", clk); //Show result in a window clk.setTo(0); // set clk image to zero for next drawing clk = back_up.clone(); // Clone the previously drawned markings from back-up image char c = waitKey(999); // Here if the parameter is 10, you will see that the second hand rotates continuously; if it is 1000, the effect is the second hand jumping second by second if (c == 27)break; } return 0; }255, 255, 0), 12, CV_AA, 0); imshow("Clock", clk); //Show result in a window clk.setTo(0); // set clk image to zero for next drawing clk = back_up.clone(); // Clone the previously drawned markings from back-up image char c = waitKey(999); // Here if the parameter is 10, you will see that the second hand rotates continuously; if it is 1000, the effect is the second hand jumping second by second if (c == 27)break; } return 0; }

          

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326444878&siteId=291194637