《学习OpenCV3》中4-1作业题

建立一个500x500大小的单通道图像,每个像素值都为0
1.创建一个ASCII数字打字机,你可以在自己的电脑上输入数字,并在一个20像素高、10像素宽的方格中显示数字。当你键入时,数字从左到右显示,知道到达图像末尾才停止。
2.允许键入回车和退格。
3.允许使用箭头来编辑每个数字。
4.创建一个键来将输出图像转化为彩色图像,每个不同的数字由不同的颜色显示。

题目如上所示。
但是,本人写的这个进行了很大的改动!

  1. 100x100像素
  2. 第三个要求没看懂
  3. 数字输出的比较丑陋,但无伤大雅
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;


/*
* @param:输入0-9的数字
* @function:输入0-9的数字,输出一个大小为10x10的矩阵,用像素点表示出来数字
* @return:返回一个10*10的表示数字的图像
*/
Mat code(char num)
{
	Mat num_code;
	switch (num)
	{
		case '0':
			num_code = Mat(10,10,CV_8UC1, Scalar(0));
			for(int i=2;i!=8;i++)
				{
					num_code.at<uchar>(i,1)=255;
					num_code.at<uchar>(i,8)=255;
					num_code.at<uchar>(8,i)=255;
					num_code.at<uchar>(1,i)=255;
				}
			num_code.at<uchar>(1,1) = 255;
			num_code.at<uchar>(1,8) = 255;
			num_code.at<uchar>(8,8) = 255;
			num_code.at<uchar>(8,1) = 255;
			break;
		case '1':
			num_code = Mat(10,10,CV_8UC1, Scalar(0));
			for(int i=2; i!=8; i++)
				num_code.at<uchar>(i,5) = 255;
			break;
		case '2':
			num_code = Mat(10,10,CV_8UC1, Scalar(0));
			for(int i=1;i!=9;i++)
			{
				num_code.at<uchar>(1,i) = 255;
				num_code.at<uchar>(5,i) = 255;
				num_code.at<uchar>(8,i) = 255;
			}
			num_code.at<uchar>(6,1) = 255;
			num_code.at<uchar>(7,1) = 255;
			num_code.at<uchar>(2,8) = 255;
			num_code.at<uchar>(3,8) = 255;
			num_code.at<uchar>(4,8) = 255;
			break;
		case '3':
			num_code = Mat(10,10,CV_8UC1, Scalar(0));
			for(int i=1;i!=9;i++)
			{
				num_code.at<uchar>(1,i) = 255;
				num_code.at<uchar>(5,i) = 255;
				num_code.at<uchar>(8,i) = 255;
				num_code.at<uchar>(i,8) = 255;
			}
			break;
		case '4':
			num_code = Mat(10,10,CV_8UC1, Scalar(0));
			for(int i=1; i!= 9; i++)
				num_code.at<uchar>(i,6) = 255;
			for(int i=1;i!=6;i++)
				num_code.at<uchar>(i,1) = 255;
			for(int i=2;i!=6;i++)
				num_code.at<uchar>(5,i) = 255;
			break;

		case '5':
			num_code = Mat(10,10,CV_8UC1, Scalar(0));
			for(int i=1;i!=9;i++)
			{
				num_code.at<uchar>(1,i) = 255;
				num_code.at<uchar>(5,i) = 255;
				num_code.at<uchar>(8,i) = 255;
			}
			num_code.at<uchar>(6,8) = 255;
			num_code.at<uchar>(7,8) = 255;
			num_code.at<uchar>(2,1) = 255;
			num_code.at<uchar>(3,1) = 255;
			num_code.at<uchar>(4,1) = 255;
			break;
		case '6':
			num_code = Mat(10,10,CV_8UC1, Scalar(0));
			for(int i=1;i!=9;i++)
				num_code.at<uchar>(i,1) =255;
			for(int i=5;i!=9;i++)
				num_code.at<uchar>(i,6) =255;
			for(int i=1; i!=7;i++)
			{
				num_code.at<uchar>(1,i) =255;
				num_code.at<uchar>(5,i) =255;
				num_code.at<uchar>(8,i) =255;
			}
			break;
		
		case '7':
			num_code = Mat(10,10,CV_8UC1, Scalar(0));
			for(int i=1;i!=7;i++)
				num_code.at<uchar>(1,i) = 255;
			for(int i=1; i!=9;i++)
				num_code.at<uchar>(i,6) = 255;
			break;

		case '8':
			num_code = Mat(10,10,CV_8UC1, Scalar(0));
			for(int i=1;i!=9;i++)
			{
				num_code.at<uchar>(i,1) =255;
				num_code.at<uchar>(i,8) =255;
				num_code.at<uchar>(1,i) =255;
				num_code.at<uchar>(5,i) =255;
				num_code.at<uchar>(8,i) =255; 
			}
			break;

		case '9':
			num_code = Mat(10,10,CV_8UC1, Scalar(0));
			for(int i=1;i!=9;i++)
			{
				num_code.at<uchar>(i,1) =255;
				num_code.at<uchar>(i,8) =255;
				num_code.at<uchar>(1,i) =255;
				num_code.at<uchar>(5,i) =255;
				num_code.at<uchar>(8,i) =255; 
			}
			num_code.at<uchar>(7,1)=0;
			num_code.at<uchar>(6,1)=0;
			break;


		default:
			break;
	}
	return num_code;
}


/*
* @param:单通道或者三通道的图像,RGB数字
* @function:把图像转化为三通道并且给白色部分涂上颜色
* @return:转化后的图像
* @Attention:如果输入图像不是单通道或者三通道,那么直接视为错误,
* 			并且返回原图像.
*/
Mat change_image_color(Mat src, int a, int b, int c)
{
	Mat dst;
	if(src.channels() == 1)
	{
		cvtColor(src, dst, COLOR_GRAY2RGB);
		for(int i=0; i!=10; i++)
			for(int j=0; j!=10; j++)
			{
				if(dst.at<Vec3b>(j,i)[1] == 255) //如果是白色,改变颜色
				{
					dst.at<Vec3b>(j,i)[0] = a; 
					dst.at<Vec3b>(j,i)[1] = b; 
					dst.at<Vec3b>(j,i)[2] = c; 
				}
				else;		// 否则就不需要改变
			}
	}
	else if(src.channels() == 3)
	{
        dst = src.clone();
		for(int i=0; i!=10; i++)
			for(int j=0; j!=10; j++)
			{
				if(dst.at<Vec3b>(j,i)[0] == 255 
				&& dst.at<Vec3b>(j,i)[1] == 255
				&& dst.at<Vec3b>(j,i)[2] == 255) //如果是白色,改变颜色
				{
					dst.at<Vec3b>(j,i)[0] = a; 
					dst.at<Vec3b>(j,i)[1] = b; 
					dst.at<Vec3b>(j,i)[2] = c; 
				}
				else;		// 否则就不需要改变
			}
	}
    else
    {
        cout << "Sorry, I can't deal with it!" <<endl;
		cout << "the result is src" <<endl;
        return src;
    }   
    
	return dst;
}




int main(int argc, char** argv)
{
	// 说明性文字
	cout << "Welcome to this screen for showing numbers!"<<endl 
		<< "You can input 0-9 to show numbers in this screen" <<endl
		<< "And you can input 'b' to clear a number" <<endl
		<< "or input 'n' to make the number happen in the next line" <<endl
		<< "or input 'c' to make the image colorful" <<endl
		<< "If you think this is useful, please remember its author" <<endl
		<< "Mr.Jing" <<endl
		<< "from UESTC";

	Mat screen = Mat(100,100,CV_8UC1,Scalar(0));
	char num;
	
	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));

	bool flag = false;
	namedWindow("显示", WINDOW_NORMAL);
	imshow("显示",screen);
	waitKey(10);

	while (true)
	{
		cin >> num;
		if((num == '0'||num == '1'||num=='2'||num == '3'||
			num=='4' || num=='5'|| num=='6'|| num=='7'||
			num=='8'|| num=='9') && flag == false)
		{
			out_ROI = code(num);
			out_ROI.copyTo(screen(work_ROI));
			imshow("显示", screen);
			if (waitKey(10)==27) break; 
			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
			{
				work_ROI.x = 100;
				work_ROI.y = 90;
				cout << "已经到底了!"<<endl;
				flag = true;
			}
			
		}
		// 回车
		else if(num=='n')
		{
			if(work_ROI.y!=100)
			{
				work_ROI.x=0;
				work_ROI.y+=10;
			}
			else
			{
				flag = true;
				cout << "No space input number!" <<endl;
			}		
		}
		// 倒退
		else if(num=='b')
		{
			Mat back_ROI = Mat(10,10,CV_8UC1,Scalar(0));	
			if(work_ROI.x!=0)
			{
				work_ROI.x -=10;
			}
			else
			{
				if(work_ROI.y==0)
					cout << "This is the first location, please input something" <<endl;
				else
				{
					work_ROI.x = 90;
					work_ROI.y -= 10;
				}
			}		
			back_ROI.copyTo(screen(work_ROI));
			imshow("显示", screen);
			if (waitKey(10)==27) break;
			flag = false;
		}
		else if(num =='c')
		{
			int a,b,c;
			RNG rng((unsigned)time(NULL));
			Mat screen_color(100,100,CV_8UC3, Scalar(0,0,0));
			Mat trasition_ROI(10,10,CV_8UC3, Scalar(0,0,0));
			Mat work_color_ROI(10,10,CV_8UC3,Scalar(0,0,0));
			for (int i = 0; i != 100; i+=10)
				for(int j=0; j!=100;j+=10)
				{		
					a = rng.uniform(0,256);
					b = rng.uniform(0,256);
					c = rng.uniform(0,256);
					work_ROI.x = j;
					work_ROI.y = i;
					
					trasition_ROI = change_image_color(screen(work_ROI),a,b,c);
					trasition_ROI.copyTo(screen_color(work_ROI));
				}			
			imshow("显示",screen_color);
			waitKey(0);
			break;
		}
		else
		{	
			cout << "Please don't input number!"<<endl;
			cout << "Please try input 'b'" <<endl;
		}
	}

	return 0;
}

后记:几日前参加工训比赛,备赛过程中,学长偶然而至。指出我基础不牢,故重新看一次书,以求牢固基础!

如文章有不妥之处,或者可以改进之地方。请评论区留言,互相帮助,努力奋进,行稳致远!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值