全国服务热线:

15861139266

opencv绘制一个模拟时钟,苏州机器视觉培训,苏州工业机器人培训
发布时间:2024-04-02 09:40:08 点击次数:151

算法背后的想法很简单:

 决定要在其中绘制模拟时钟的窗口的大小。这里的窗口大小是 640 * 640。

因此这个窗口的中心是 (320,320)作为圆心画一个圆(圆的大小应该小于窗口的大小)现在我们需要在圆的圆周上有时针和秒针的标记 时针和秒针的坐标可以通过使用圆参数方程得到:

image.png

由于中心的坐标是 (Cx,Cy)因此该点的坐标将是


x1=Cx+rCos(θ)


y1= Cy + rsin(θ)




因此,在获得坐标后,我们需要为分钟和小时标记画一条线

对于时针的标记:我们取外圆半径为:315内圈半径为:275

对于分针的标记:我们取外圆的半径为:315内圈为:275



注意:


由于 12 小时对应于时针旋转 360 度


因此,一小时分针应旋转 360/12=30 度


 因此角度,时针会变化 30 度

每旋转 30 度,我们有 5 分钟


  因此,每分钟,分针应旋转 30/5=6  度      


 因此,分针的角度会变化 6 度

 180 度 = π 弧度 因此 θ 度= (θ*π/180) 弧度




接下来我们需要用系统时钟更新我们的时针、分针和秒针。




代码如下


#include <iostream>

#include "opencv2/highgui/highgui.hpp"

#include "opencv2/imgproc/imgproc_c.h"

#include "opencv2/imgproc/imgproc.hpp"

#include <stdio.h>

#include <ctime>

#include <sys/timeb.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(0, 0);

    int rad = 320;

    float sec_angle, min_angle, hour_angle;




    //Draw second markings

    int s1[60][2];

    for (int i = 0; i < 60; i++)

        for (int j = 0; j < 2; j++)

            if (j % 2 == 0)

                s1[i][j] = 320 + 295 * cos(6.0 * i * 3.14 / 180);

            else

                s1[i][j] = 320 + 295 * sin(6.0 * i * 3.14 / 180);


    int s2[60][2];

    for (int i = 0; i < 60; i++)

        for (int j = 0; j < 2; j++)

            if (j % 2 == 0)

                s2[i][j] = 320 + 315 * cos(6.0 * i * 3.14 / 180);

            else

                s2[i][j] = 320 + 315 * sin(6.0 * i * 3.14 / 180);


    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];

    for (int i = 0; i < 12; i++)

        for (int j = 0; j < 2; j++)

            if (j % 2 == 0)

                h1[i][j] = 320 + 275 * cos(30.0 * i * 3.14 / 180);

            else

                h1[i][j] = 320 + 275 * sin(30.0 * i * 3.14 / 180);


    int h2[12][2];

    for (int i = 0; i < 12; i++)

        for (int j = 0; j < 2; j++)

            if (j % 2 == 0)

                h2[i][j] = 320 + 315 * cos(30.0 * i * 3.14 / 180);

            else

                h2[i][j] = 320 + 315 * sin(30.0 * i * 3.14 / 180);

    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); //Draw 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 it to a local variable

        ftime(&tmb);

        rawtime = tmb.time;



        localtime_s(&timeinfo,&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;                        //Convert minute to angle


        if (hour > 12)hour = hour - 12;

        hour_angle = (hour * 30) + (minute * .5) + 270;  //Convert 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;


        //Find out the co-ordinates in the circle perimeter for second and draw the line from center

        perim.x = (int)(cent.x + (rad - 5) * cos(sec_angle * CV_PI / 180.0));

        perim.y = (int)(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);



        //Find out the co-ordinates on the circle perimeter for minute and draw the line from center

        perim.x = (int)(cent.x + (rad - 50) * cos(min_angle * CV_PI / 180.0));

        perim.y = (int)(cent.y + (rad - 50) * sin(min_angle * CV_PI / 180.0));

        line(clk, cent, perim, Scalar(0, 255, 255, 0), 4, CV_AA, 0);



        //Find out the co-ordinates on the circle perimeter for hour and draw the line from center

        perim.x = (int)(cent.x + (rad - 75) * cos(hour_angle * CV_PI / 180.0));

        perim.y = (int)(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;

}

效果如图:

image.png


立即咨询
  • 品质服务

    服务贴心周到

  • 快速响应

    全天24小时随时沟通

  • 专业服务

    授权率高,保密性强

  • 完善售后服务

    快速响应需求,及时性服务

直播课程
软件开发基础课程
上位机软件开发课
机器视觉软件开发课
专题课
联系方式
电话:15861139266
邮箱:75607082@qq.com
地址:苏州吴中区木渎镇尧峰路69号
关注我们

版权所有:江苏和讯自动化设备有限公司所有 备案号:苏ICP备2022010314号-1

技术支持: 易动力网络