创建ASCII数字打印机(OpenCV C++)

学习OpenCV3(中文版)Learning OpenCV 3 Computer Vision in C++ with the OpenCV Library 第四章练习1

建立一个500×500大小的单通道图像,每个像素值都为0。
a.创建一个ASCII数字打印机,你可以在自己电脑上输入数字,并在一个20像素高、10像素宽的方块中显示数字。当你键入时,数字将从左到右显示,直到到达图像的末尾才停止。
b.允许键入回车和退格。
c.允许使用箭头来编辑每个数字。
d.创建一个健来将输出图像转换为彩色图像,每个不同的数字由不同的颜色显示。
创建ASCII数字打印机(OpenCV C++)_第1张图片
**在这里,为了方便,我将屏幕的500×500换成了100×100,数字显示将20高、10宽换成了10高、10宽。

b退格,e回车,k空格,q退出
w s a d 上下左右
c一键变彩色,作为最后显示使用(只写了绿色,绿色好看)
创建ASCII数字打印机(OpenCV C++)_第2张图片

#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)那么完全卡住显示不出,不知道这里面是个怎么运作的,(如果有知道的小伙伴评论跟我说一下哈)

你可能感兴趣的:(opencv,c++,cv)