本文共 7500 字,大约阅读时间需要 25 分钟。
建立一个500×500大小的单通道图像,每个像素值都为0。
a.创建一个ASCII数字打印机,你可以在自己电脑上输入数字,并在一个20像素高、10像素宽的方块中显示数字。当你键入时,数字将从左到右显示,直到到达图像的末尾才停止。 b.允许键入回车和退格。 c.允许使用箭头来编辑每个数字。 d.创建一个健来将输出图像转换为彩色图像,每个不同的数字由不同的颜色显示。 **在这里,为了方便,我将屏幕的500×500换成了100×100,数字显示将20高、10宽换成了10高、10宽。b退格,e回车,k空格,q退出
w s a d 上下左右 c一键变彩色,作为最后显示使用(只写了绿色,绿色好看)#include#include #include using namespace cv;using namespace std;Mat code(char num) // 数字0-9的编码 10*10 的矩阵{ Mat_ num_code;//好处就是后面无需使用.at switch (num) { case '0': num_code = Mat(10, 10, CV_8UC1, Scalar(0)); for (int i = 2; i < 8; i++) { num_code(1, i) = 255; num_code(7, i) = 255; num_code(i, 2) = 255; num_code(i, 7) = 255; } return num_code; case '1': num_code = Mat(10, 10, CV_8UC1, Scalar(0)); for (int i = 1; i < 8; i++) { num_code(i, 7) = 255; } return num_code; case '2': num_code = Mat(10, 10, CV_8UC1, Scalar(0)); for (int i = 2; i < 8; i++) { num_code(1, i) = 255; num_code(4, i) = 255; num_code(7, i) = 255; } num_code(2, 7) = 255; num_code(3, 7) = 255; num_code(5, 2) = 255; num_code(6, 2) = 255; return num_code; case '3': num_code = Mat(10, 10, CV_8UC1, Scalar(0)); for (int i = 2; i < 8; i++) { num_code(1, i) = 255; num_code(4, i) = 255; num_code(7, i) = 255; } num_code(2, 7) = 255; num_code(3, 7) = 255; num_code(5, 7) = 255; num_code(6, 7) = 255; return num_code; case '4': num_code = Mat(10, 10, CV_8UC1, Scalar(0)); for (int i = 1; i < 8; i++) { num_code(i, 7) = 255; } for (int i = 1; i < 5; i++) { num_code(i, 2) = 255; } num_code(4, 3) = 255; num_code(4, 4) = 255; num_code(4, 5) = 255; num_code(4, 6) = 255; return num_code; case '5': num_code = Mat(10, 10, CV_8UC1, Scalar(0)); for (int i = 2; i < 8; i++) { num_code(1, i) = 255; num_code(4, i) = 255; num_code(7, i) = 255; } num_code(2, 2) = 255; num_code(3, 2) = 255; num_code(5, 7) = 255; num_code(6, 7) = 255; return num_code; case '6': num_code = Mat(10, 10, CV_8UC1, Scalar(0)); for (int i = 2; i < 8; i++) { num_code(1, i) = 255; num_code(4, i) = 255; num_code(7, i) = 255; } num_code(2, 2) = 255; num_code(3, 2) = 255; num_code(5, 2) = 255; num_code(6, 2) = 255; num_code(5, 7) = 255; num_code(6, 7) = 255; return num_code; case '7': num_code = Mat(10, 10, CV_8UC1, Scalar(0)); for (int i = 3; i < 8; i++) { num_code(1, i) = 255; } for (int i = 2; i < 8; i++) { num_code(i, 7) = 255; } return num_code; case '8': num_code = Mat(10, 10, CV_8UC1, Scalar(0)); for (int i = 2; i < 8; i++) { num_code(1, i) = 255; num_code(4, i) = 255; num_code(7, i) = 255; } num_code(2, 2) = 255; num_code(3, 2) = 255; num_code(5, 2) = 255; num_code(6, 2) = 255; num_code(5, 7) = 255; num_code(6, 7) = 255; num_code(2, 7) = 255; num_code(3, 7) = 255; return num_code; case '9': num_code = Mat(10, 10, CV_8UC1, Scalar(0)); for (int i = 2; i < 8; i++) { num_code(1, i) = 255; num_code(4, i) = 255; num_code(7, i) = 255; } num_code(2, 2) = 255; num_code(3, 2) = 255; num_code(2, 7) = 255; num_code(3, 7) = 255; num_code(5, 7) = 255; num_code(6, 7) = 255; } return num_code;}int main(){ cout << "ASCII数字打印机" << endl << "制作人:河边一只猫" << endl << "b退格,e回车,k空格,q退出" << endl << "w s a d 上下左右" << endl << "c一键变彩色,作为最后显示使用" << endl; Mat scr = Mat(100, 100, CV_8UC1);//定义屏幕screen简称scr100*100的显示 scr.setTo(0);//全黑屏幕 Rect work_ROI;//数字填充区域 work_ROI.x = 0; work_ROI.y = 0; work_ROI.width = 10; work_ROI.height = 10; Mat out_ROI = Mat(10, 10, CV_8UC1, Scalar(0));//输出小块初始化全黑 char control;//检测输入 bool flag = false;//判断是否屏幕装满了 namedWindow("显示", WINDOW_NORMAL); imshow("显示", scr); waitKey(10); while (1) { control = _getch(); //输入的为数字************************************************************** if (control == '0' || control == '1' || control == '2' || control == '3' || control == '4' || control == '5' || control == '6' || control == '7' || control == '8' || control == '9') { out_ROI = code(control);//给输出小块编码 out_ROI.copyTo(scr(work_ROI));//把输出小块复制到屏幕的填充区域 imshow("显示", scr); waitKey(10); if (work_ROI.y != 90 || work_ROI.x != 90)//如果没装满 { if (work_ROI.x == 90)//如果横坐标为90了,需要换行 { work_ROI.x = 0;//让横坐标为0 work_ROI.y += 10;//纵坐标加10 } else { work_ROI.x += 10;//横坐标加10 } } else { cout << "已经到底了!" << endl; flag = true;//标志屏幕已满 } } //输入的为b ************************************************************** else if (control == 'b')//退格 { if (flag)//如果已经到满了 { out_ROI.setTo(0); out_ROI.copyTo(scr(work_ROI)); imshow("显示", scr); waitKey(10); flag = false;//说屏幕没满,不然删完一个就删不了其他 } else//如果屏幕没满 { if (work_ROI.y > 0 || work_ROI.x > 0) { if (work_ROI.x == 0) { work_ROI.y -= 10; work_ROI.x = 90; } else { work_ROI.x -= 10; } out_ROI.setTo(0); out_ROI.copyTo(scr(work_ROI)); imshow("显示", scr); waitKey(10); } else { cout << "已经删完了!" << endl; } } } //输入的为e ************************************************************** else if (control == 'e')//回车 { imshow("显示", scr); waitKey(10); if (work_ROI.y != 90) { work_ROI.x = 0; work_ROI.y += 10; } else { cout << "已经到底了!" << endl; } } //输入的为空格************************************************************** else if (control == 'k')//空格 { out_ROI.setTo(0); out_ROI.copyTo(scr(work_ROI)); imshow("显示", scr); waitKey(10); if (work_ROI.y != 90 || work_ROI.x != 90) { if (work_ROI.x == 90) { work_ROI.x = 0; work_ROI.y += 10; } else { work_ROI.x += 10; } } else { cout << "屏幕装满了!" << endl; } } //输入的为q ************************************************************** else if (control == 'q')//退出 { break; } //输入的为w ************************************************************** else if (control == 'w')//上 { if (work_ROI.y != 0) { work_ROI.y -= 10; } else { cout << "到最上了!" << endl; } } //输入的为w ************************************************************** else if (control == 's')//下 { if (work_ROI.y != 90) { work_ROI.y += 10; } else { cout << "到最下了!" << endl; } } //输入的为w ************************************************************** else if (control == 'a')//左 { if ( work_ROI.x != 0) { work_ROI.x -= 10; } else { cout << "到最左了!" << endl; } } //输入的为w ************************************************************** else if (control == 'd')//右 { if (work_ROI.x != 90) { work_ROI.x += 10; } else { cout << "到最右了!" << endl; } } //输入的为c ************************************************************** else if (control == 'c')//COLORFUL { cvtColor(scr, scr, COLOR_GRAY2BGR);//灰度图转换为彩色图 for (int j = 0; j < 100; j ++) { for(int i = 0;i<100;i++) { if ((int)scr.at (i, j)[0] == 255&& (int)scr.at (i, j)[1] == 255 && (int)scr.at (i, j)[2] == 255 ) { scr.at (i,j)[0] = 0; scr.at (i,j)[2] = 0; } } } imshow("显示", scr); waitKey(10); break;//展示完彩色就得自动退出程序。 } } //如果你发现屏幕太小了,又不能放大 //那么就先q一下退出循环后,再放大屏幕一次,之后再重新运行程序即可 waitKey(0); return 0;}
总结:关于动态显示图片的时候,不知道为什么每次更新一次后都要加一句延时,如果不加waitKey(10)那么完全卡住显示不出,不知道这里面是个怎么运作的,(如果有知道的小伙伴评论跟我说一下哈)
转载地址:http://hamen.baihongyu.com/