虽然OpenCV的绘图函数不少时候能帮上忙,它们毕竟终究只是配角。直到看到外国友人的一篇blog,我沉默了。
将其代码拿出来跑效果是这样的(.gif):
只能说,人有多大胆,地有多大产。
其实实现方法也很简单,调用系统的时间,利用三角函数转化成角度,再用OpenCV的绘图函数将钟画出来,更准确地说,是一帧一帧把指针画上去,画一遍擦一遍。
以下是代码,供参考:
#include <iostream> #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc_c.h" #include "opencv2/imgproc/imgproc.hpp" #include <stdio.h> #include <time.h> #include <sys/timeb.h> #include <sys/time.h> using namespace std; using namespace cv; int main() { Mat clk(640,640,CV_8UC3); //Mat to store clock image Mat back_up(640,640,CV_8UC3); //Mat to store backup image Point cent(320,320); Point perim(320,0); int rad =320; float sec_angle=270; float min_angle=330; float hour_angle=210; //Draw second markings int s1[60][2]={{320,25},{351,27},{381,31},{411,39},{440,51},{468,65},{493,81},{517,101},{539,123}, \ {559,147},{575,173},{589,200},{601,229},{609,259},{613,289},{615,320},{613,351},{609,381},{601,411}, \ {589,440},{575,468},{559,493},{539,517},{517,539},{493,559},{468,575},{440,589},{411,601},{381,609}, \ {351,613},{320,615},{289,613},{259,609},{229,601},{200,589},{173,575},{147,559},{123,539},{101,517}, \ {81,493},{65,468},{51,440},{39,411},{31,381},{27,351},{25,320},{27,289},{31,259},{39,229},{51,200}, \ {65,173},{81,147},{101,123},{123,101},{147,81},{172,65},{200,51},{229,39},{259,31},{289,27},}; int s2[60][2]={{320,5},{353,7},{385,12},{417,20},{448,32},{478,47},{505,65},{531,86},{554,109}, \ {575,135},{593,163},{608,192},{620,223},{628,255},{633,287},{635,320},{633,353},{628,385},{620,417}, \ {608,448},{593,478},{575,505},{554,531},{531,554},{505,575},{478,593},{448,608},{417,620},{385,628}, \ {353,633},{320,635},{287,633},{255,628},{223,620},{192,608},{163,593},{135,575},{109,554},{86,531}, \ {65,505},{47,478},{32,448},{20,417},{12,385},{7,353},{5,320},{7,287},{12,255},{20,223},{32,192}, \ {47,163},{65,135},{86,109},{109,86},{135,65},{162,47},{192,32},{223,20},{255,12},{287,7}}; for(int i=0;i<60;i++){ line(clk,Point(s1[i][0],s1[i][1]),Point(s2[i][0],s2[i][1]), Scalar(0,255,0,0), 1.5,CV_AA,0); } //Draw hour markings int h1[12][2]={{320,45},{458,82},{558,183},{595,320},{558,458},{458,558},{320,595},{183,558}, \ {82,458},{45,320},{82,183},{182,82}}; int h2[12][2]={{320,5},{478,47},{593,163},{635,320},{593,478},{478,593},{320,635},{163,593}, \ {47,478},{5,320},{47,163},{162,47}}; for(int i=0;i<12;i++){ line(clk,Point(h1[i][0],h1[i][1]),Point(h2[i][0],h2[i][1]), Scalar(0,255,0,0), 4,CV_AA,0); } circle(clk,cent,rad-5,Scalar(0,0,255,0),4,CV_AA,0); //Dreaw outercircle of clock circle(clk,cent,1,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){ //Access system time and store to local variable 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; //Fond out the co-ordinates in the circle perimeter for second and draw the line from center perim.x = (int)round(cent.x + (rad-5) * cos(sec_angle * CV_PI / 180.0)); perim.y = (int)round(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); //Fond out the co-ordinates on the circle perimeter for minute and draw the line from center perim.x = (int)round(cent.x + (rad-50) * cos(min_angle * CV_PI / 180.0)); perim.y = (int)round(cent.y + (rad-50) * sin(min_angle * CV_PI / 180.0)); line(clk,cent,perim, Scalar(0,255,255,0), 4,CV_AA,0); //Fond out the co-ordinates on the circle perimeter for hour and draw the line from center perim.x = (int)round(cent.x + (rad-75) * cos(hour_angle * CV_PI / 180.0)); perim.y = (int)round(cent.y + (rad-75) * sin(hour_angle * CV_PI / 180.0)); line(clk,cent,perim, Scalar(0,255,255,0), 8,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(10); // Wait for few millisecond and go back to loop. if(c==27)break; } return 0; }