【OpenCV 学习之路】(5)画出时钟并动态同步系统时间之二

版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/u011897411/article/details/80326191

画好了轮廓之后(关于画轮廓的内容),我们需要做的是把时针,分针,秒针画出来,单纯地画出来其实也很简单,只要确定终点就行了,起点就是圆心。
先看效果图:
效果图

>Talk is cheap,show you the code.
#include<opencv2\core\core.hpp>  
#include<opencv2\highgui\highgui.hpp>  
#include<opencv2\imgproc\imgproc.hpp> 
#include<time.h> 
#include<sys/timeb.h> 
#include<sys\utime.h>  
using namespace cv;
int main()
{
    Mat clock_background(500, 500, CV_8UC3, Scalar::all(0));//创一个背景
    int radius = clock_background.cols / 2;//设半径
    Point center(clock_background.cols / 2, clock_background.rows / 2);//设圆心
    circle(clock_background, center, radius, Scalar(255, 100, 0), 1, 8, 0);//画时钟外轮廓
    circle(clock_background, center, 5, Scalar(0, 0, 255), -1, 8, 0);//画圆心
    Point second_begin, second_end;//设刻度的起点,终点
    int scale_long = 10;//刻度的长度
    int scale_width = 2;//刻度的宽度
    //画一个背景
    for (int second_Scale = 0; second_Scale < 60; second_Scale++)
    {
        if (second_Scale % 5 == 0)//每五个刻度就变长度,也就是整点1,2,3,···,12这些数字对应的刻度长一点
        {
            scale_long = 20;
            scale_width = 5;
        }
        else
        {
            scale_long = 10;
            scale_width = 2;
        }
        second_begin.x = center.x + radius * cos(6 * second_Scale* CV_PI / 180);//刻度的起点x坐标赋值
        second_begin.y = center.y + radius * sin(6 * second_Scale* CV_PI / 180);//刻度的起点y坐标赋值
        second_end.x = center.x + (radius - scale_long) * cos(6 * second_Scale* CV_PI / 180);//刻度的终点x坐标赋值
        second_end.y = center.y + (radius - scale_long) * sin(6 * second_Scale* CV_PI / 180);//刻度的终点y坐标赋值
        line(clock_background, second_begin, second_end, Scalar(50, 205, 50), scale_width);//连接起点终点
    }
    int secong_hand_long = radius*0.9, min_hand_long= radius*0.7, hour_hand_long= radius*0.5;//秒针,分针,时针的长度设置
    Point secong_hand_end, min_hand_end, hour_hand_end;//秒针分针时针的终点
    Mat clk = clock_background.clone();//新建一个clk刷新

    float seconds, min, hour, millisec;//秒,分,时,更精确的秒(千分之一秒)
    time_t time_seconds = time(0);
    struct tm now_time;
    struct timeb tmb;

    while (1)
    {
        //获取系统时间
        ftime(&tmb);
        time_seconds = tmb.time;
        localtime_s(&now_time, &time_seconds);

        seconds = (float)now_time.tm_sec;//系统时钟赋值给  seconds
        min        = (float)now_time.tm_min;//系统时钟赋值给  min
        hour    = (float)now_time.tm_hour;//系统时钟赋值给 hour
        millisec = tmb.millitm;//

        printf_s("s=%f\t", seconds);
        printf_s("m=%f\t", min);
        printf_s("h=%f\t", hour);

        seconds = seconds + millisec / 1000;
        min = min + seconds / 60.0;
        if (hour > 12) hour = hour - 12;
        hour = hour + min / 60.0;

        //秒针
        secong_hand_end.x = (int)(center.x + (float)secong_hand_long * cos(3 * CV_PI / 2 + seconds * CV_PI / 30));
        secong_hand_end.y = (int)(center.y + (float)secong_hand_long * sin(3 * CV_PI / 2 + seconds * CV_PI / 30));
        line(clk, center, secong_hand_end, Scalar(147, 231, 255), 1.5, CV_AA, 0);

        //分针
        min_hand_end.x = (int)(center.x + min_hand_long * cos(3*CV_PI/2+min*CV_PI/30));
        min_hand_end.y = (int)(center.y + min_hand_long * sin(3*CV_PI/2+min*CV_PI/30));
        line(clk, center, min_hand_end, Scalar(147, 231, 255), 4, CV_AA, 0);

        //时针
        hour_hand_end.x = (int)(center.x + hour_hand_long * cos(3*CV_PI/2+hour*CV_PI/6));
        hour_hand_end.y = (int)(center.y + hour_hand_long * sin(3*CV_PI/2+hour*CV_PI/6));
        line(clk, center, hour_hand_end, Scalar(147, 231, 255), 12, CV_AA, 0);

        imshow("clock", clk);

        clk.setTo(0);
        clk = clock_background.clone();
        waitKey(1000);//这里如果参数为10,则看到的是秒针连续地转动;如果是1000,则效果是秒针一秒一秒地跳动 
    }

到了这里,其实主要是获取到的秒,分,时看你怎么用,把它的具体数值转换成角度,再根据角度写出终点的坐标即可实现。
一开始写代码的时候我也是只获取系统的时分秒,没有精确到小数点后的,也就是得到 1秒,2秒,3秒。这样的效果导致时针分针不会根据实际时间变化,什么意思呢?
比如说时间 17时23分12秒,
时针直直的指在数字5,分针指在23,秒针指在12,
还不明白?看看现实的钟你会发现。除了五点整之外,时针还会直直的指在5那里吗?
然后再对比下 @冰不语 的代码,发现它还获取了 比如说 1.213秒这么高精确度的秒数,然后我也加上,就可以实现了。

同时,我个人尝试过编译@冰不语 的代码 @冰不语的文章,但是会有错误,同时他的博客下面也有人提出了,和我遇到一样的错误。我去尝试按照 评论的方法修改,仍然不行,最终我找到了解决方法,如果有小伙伴也遇到了可以下载附件看一看,对比对比,其实错误原因是获取高精确度的秒数导致的。 附件里包含了:原作者的代码,@冰不语的代码,和我自己的代码。

附件地址:https://download.csdn.net/download/u011897411/10416302

猜你喜欢

转载自blog.csdn.net/u011897411/article/details/80326191
今日推荐