建立一个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_<uchar> 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<Vec3b>(i, j)[0] == 255&& (int)scr.at<Vec3b>(i, j)[1] == 255 && (int)scr.at<Vec3b>(i, j)[2] == 255 )
{
scr.at<Vec3b>(i,j)[0] = 0;
scr.at<Vec3b>(i,j)[2] = 0;
}
}
}
imshow("显示", scr);
waitKey(10);
break;//展示完彩色就得自动退出程序。
}
}
//如果你发现屏幕太小了,又不能放大
//那么就先q一下退出循环后,再放大屏幕一次,之后再重新运行程序即可
waitKey(0);
return 0;
}
总结:关于动态显示图片的时候,不知道为什么每次更新一次后都要加一句延时,如果不加waitKey(10)那么完全卡住显示不出,不知道这里面是个怎么运作的,(如果有知道的小伙伴评论跟我说一下哈)