Learning OpenCV3课后习题4.1

基于visualstudio 2019实现的

先上效果图吧

 实现的功能有:

a.实现0-9数字输入

b.自动换行

c.箭头变换位置

d.esc按键结束变成彩色凸显(不同数字不一样)

下面是具体实现

void num_color_stream()//所有功能基本集合到这一个函数了
{
//----------------------在10*20方块里画数字0-9,都是LED风格的------------------------
cv::Mat u = cv::Mat::zeros(20, 10, CV_8UC1);//创造10*20的uchar类型元素,里面都是0
cv::Mat m1_1 = u(cv::Range(1, 2), cv::Range(1, 9));
m1_1.setTo((uchar)255);
cv::Mat m1_2 = u(cv::Range(2, 3), cv::Range(2, 8));
m1_2.setTo((uchar)255);
//这是在画上边


cv::Mat m = cv::Mat::zeros(20, 10, CV_8UC1);
cv::Mat m_1 = m(cv::Range(9, 11), cv::Range(2, 8));
m_1.setTo((uchar)255);
//这是在画中间


cv::Mat l = cv::Mat::zeros(20, 10, CV_8UC1);
cv::Mat l_1 = l(cv::Range(18, 19), cv::Range(1, 9));
l_1.setTo((uchar)255);
cv::Mat l_2 = l(cv::Range(17, 18), cv::Range(2, 8));
l_2.setTo((uchar)255);
//这是在画下边


cv::Mat ul = cv::Mat::zeros(20, 10, CV_8UC1);
cv::Mat m2_1 = ul(cv::Range(3, 9), cv::Range(1, 2));
m2_1.setTo((uchar)255);
cv::Mat m2_2 = ul(cv::Range(4, 8), cv::Range(2, 3));
m2_2.setTo((uchar)255);
//这是在画上半部分的左边


cv::Mat ll = cv::Mat::zeros(20, 10, CV_8UC1);
cv::Mat ll_1 = ll(cv::Range(11, 17), cv::Range(1, 2));
ll_1.setTo((uchar)255);
cv::Mat ll_2 = ll(cv::Range(12, 16), cv::Range(2, 3));
ll_2.setTo((uchar)255);
//这是在画下半部分的左边


cv::Mat ur = cv::Mat::zeros(20, 10, CV_8UC1);
cv::Mat m3_1 = ur(cv::Range(3, 9), cv::Range(8, 9));
m3_1.setTo((uchar)255);
cv::Mat m3_2 = ur(cv::Range(4, 8), cv::Range(7, 8));
m3_2.setTo((uchar)255);
//这是在画上半部分的右边

cv::Mat lr = cv::Mat::zeros(20, 10, CV_8UC1);
cv::Mat lr_1 = lr(cv::Range(11, 17), cv::Range(8, 9));
lr_1.setTo((uchar)255);
cv::Mat lr_2 = lr(cv::Range(12, 16), cv::Range(7, 8));
lr_2.setTo((uchar)255);
//这是在画下半部分的右边


//----------------------将上面画的这些元素组合起来就是0-9了------------------------
cv::Mat num_0 = u + ul + ur + ll + lr + l;
cv::Mat num_1 = ur + lr;
cv::Mat num_2 = u + ur + ll + m + l;
cv::Mat num_3 = u + ur + lr + m + l;
cv::Mat num_4 = ul + ur + m + lr;
cv::Mat num_5 = u + lr + ul + m + l;
cv::Mat num_6 = u + lr + ul + m + l + ll;
cv::Mat num_7 = ur + lr + u;
cv::Mat num_8 = u + ul + ur + ll + lr + l + m;
cv::Mat num_9 = u + ul + ur + lr + l + m;

//----------------------下面开始写功能------------------------
cv::Mat arr = cv::Mat::zeros(500, 500, CV_8UC1);//画500*500背景
int c;//读取的键位
int i = 0, j = 0;//i目前的左上角位置,j目前的右上角位置

for (;;)
{
    if ((i == 500) && (j <= 460))//判断是否到达右边界,如果到达切换下一行
    {
        j += 20;
        i = 0;
    }
    c = cv::waitKeyEx(11);//读取输入的键位ASCII码,用waitkey读取不了上下左右
//用waitKeyEx才行

    if (c == '0' && i != 500)//判断是否输入0
    {
        cv::Mat ele = arr(cv::Rect(i, j, 10, 20));
        ele.setTo((uchar)0);
        ele.setTo((uchar)255, num_0);
        i += 10;
    }
    if (c == '1' && i != 500)//判断是否输入1
    {
        cv::Mat ele = arr(cv::Rect(i, j, 10, 20));
        ele.setTo((uchar)0);
        ele.setTo((uchar)255, num_1);
        i += 10;
    }
    if (c == '2' && i != 500)//判断是否输入2
    {
        cv::Mat ele = arr(cv::Rect(i, j, 10, 20));
        ele.setTo((uchar)0);
        ele.setTo((uchar)255, num_2);
        i += 10;
    }
    if (c == '3' && i != 500)//判断是否输入3
    {
        cv::Mat ele = arr(cv::Rect(i, j, 10, 20));
        ele.setTo((uchar)0);
        ele.setTo((uchar)255, num_3);
        i += 10;
    }
    if (c == '4' && i != 500)//判断是否输入4
    {
        cv::Mat ele = arr(cv::Rect(i, j, 10, 20));
        ele.setTo((uchar)0);
        ele.setTo((uchar)255, num_4);
        i += 10;
    }
    if (c == '5' && i != 500)//判断是否输入5
    {
        cv::Mat ele = arr(cv::Rect(i, j, 10, 20));
        ele.setTo((uchar)0);
        ele.setTo((uchar)255, num_5);
        i += 10;
    }
    if (c == '6' && i != 500)//判断是否输入6
    {
        cv::Mat ele = arr(cv::Rect(i, j, 10, 20));
        ele.setTo((uchar)0);
        ele.setTo((uchar)255, num_6);
        i += 10;
    }
    if (c == '7' && i != 500)//判断是否输入7
    {
        cv::Mat ele = arr(cv::Rect(i, j, 10, 20));
        ele.setTo((uchar)0);
        ele.setTo((uchar)255, num_7);
        i += 10;
    }
    if (c == '8' && i != 500)//判断是否输入8
    {
        cv::Mat ele = arr(cv::Rect(i, j, 10, 20));
        ele.setTo((uchar)0);
        ele.setTo((uchar)255, num_8);
        i += 10;
    }
    if (c == '9' && i != 500)//判断是否输入9
    {
        cv::Mat ele = arr(cv::Rect(i, j, 10, 20));
        ele.setTo((uchar)0);
        ele.setTo((uchar)255, num_9);
        i += 10;
    }
    if (c == 8 && i >= 10)//backspace's ASCII is 8
    {
        i -= 10;
        cv::Mat ele = arr(cv::Rect(i, 0, 10, 20));
        ele.setTo((uchar)0);
    }
    if (c == 13 && j <= 460)//回车键 是 13
    {
        j += 20;
        i = 0;
    }
    
    if (c == 2424832&&i!=0)//左
    {
        i -= 10;
        
    }
    if (c == 2555904 )//右 这里不用判断了是否达到边界了
//因为if ((i == 500) && (j <= 460))可以自动切换到下一行
    {
        i += 10;
    }
    if (c == 2490368 && j != 0)//上
    {
        j -= 20;
    
    }
    if (c ==2621440 && j != 480)//下
    {
        j += 20;
        
    }
    if (c == 27)break;//按esc退出
    cv::imshow("windows", arr);//显示操作效果
    /*if(c!=-1)
    cout << "key=" << c << endl;*/
}
//----------------------将上面图形变成彩色图像(不同数字不一样)------------------------
cv::Mat colormat(500, 500, CV_8UC3);//创建500*500的3通道uchar图像
colormat.setTo(cv::Vec3b(0, 0, 0));//背景设为0
for (int y = 0; y != 25; ++y)//读取每一行
for (int x = 0; x != 50; ++x)//读取每一列,x和y是当前位置
{
    cv::Mat comp = arr(cv::Rect(x * 10, y * 20, 10, 20));
//在当前位置构造一个10*20的区域


    //这里的compareMat是自己写的,作用是比较当前区域和哪个数字一样

    /*bool compareMat(const cv::Mat& a, const cv::Mat& b)
    {
        cv::Mat eq = (a != b);
//eq是一个同样大小的图片,如果a和b相同,那么eq里面就全是0了
        return cv::countNonZero(eq) == 0;//全是0就返回真
    }*/


    if (compareMat(comp, num_0))//判断是否和数字0一样
    {
        cv::Mat color_0 = colormat(cv::Rect(x * 10, y * 20, 10, 20));
//构造10*20区域
        color_0.setTo(cv::Vec3b(255, 0, 0), num_0);
//以num_0为模板显示0,opencv里的rgb是反的,即bgr(255,0,0)是蓝色
    }
    if (compareMat(comp, num_1))//判断是否和数字1一样
    {
        cv::Mat color_0 = colormat(cv::Rect(x * 10, y * 20, 10, 20));
        color_0.setTo(cv::Vec3b(0, 255, 0), num_1);
    }
    if (compareMat(comp, num_2))//判断是否和数字2一样
    {
        cv::Mat color_0 = colormat(cv::Rect(x * 10, y * 20, 10, 20));
        color_0.setTo(cv::Vec3b(0, 0, 255), num_2);
    }
    if (compareMat(comp, num_3))//判断是否和数字3一样
    {
        cv::Mat color_0 = colormat(cv::Rect(x * 10, y * 20, 10, 20));
        color_0.setTo(cv::Vec3b(255, 255, 0), num_3);
    }
    if (compareMat(comp, num_4))//判断是否和数字4一样
    {
        cv::Mat color_0 = colormat(cv::Rect(x * 10, y * 20, 10, 20));
        color_0.setTo(cv::Vec3b(255, 0, 255), num_4);
    }
    if (compareMat(comp, num_5))//判断是否和数字5一样
    {
        cv::Mat color_0 = colormat(cv::Rect(x * 10, y * 20, 10, 20));
        color_0.setTo(cv::Vec3b(0, 255, 255), num_5);
    }
    if (compareMat(comp, num_6))//判断是否和数字6一样
    {
        cv::Mat color_0 = colormat(cv::Rect(x * 10, y * 20, 10, 20));
        color_0.setTo(cv::Vec3b(255, 255, 255), num_6);
    }
    if (compareMat(comp, num_7))//判断是否和数字7一样
    {
        cv::Mat color_0 = colormat(cv::Rect(x * 10, y * 20, 10, 20));
        color_0.setTo(cv::Vec3b(255, 255, 128), num_7);
    }
    if (compareMat(comp, num_8))//判断是否和数字8一样
    {
        cv::Mat color_0 = colormat(cv::Rect(x * 10, y * 20, 10, 20));
        color_0.setTo(cv::Vec3b(255, 128, 255), num_8);
    }
    if (compareMat(comp, num_9))//判断是否和数字9一样
    {
        cv::Mat color_0 = colormat(cv::Rect(x * 10, y * 20, 10, 20));
        color_0.setTo(cv::Vec3b(128, 255, 255), num_9);
    }
}
cv::imshow("windows2", colormat);//最后当然是效果展示了
cv::waitKey(0);
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值