opencv入门 二

目录

  • 滚动条操作
  • 键盘响应操作
  • 颜色表
  • 图像像素的逻辑操作
  • 位操作

滚动条操作

//Mat对象
Mat dst, m, src;
int lightness = 50; //初始亮度
void on_track(int, void *)
{
	//初始化m对象
	m = Scalar(lightness, lightness, lightness);
	cv::add(src, m, dst);	//增加光的亮度
	
	//将dst放在主布局nameWindow之下
	imshow("亮度调整", dst);
}

void QuickDemo::tracking_bar_demo(Mat& image) 
{
	//nameWindow属于主布局
	namedWindow("亮度调整", WINDOW_AUTOSIZE);
	dst = Mat::zeros(image.size(), image.type());
	m = Mat::zeros(image.size(), image.type());
	src = image.clone();	//深拷贝

	int max_value = 100;
	//当滚动按钮被拖动的时候,on_track函数会去调整光的亮度
	createTrackbar("亮度调整: ", "亮度调整", &lightness, 
								max_value, on_track);
	on_track(50, 0);		//固定写法
}


//main.cpp
int main()		
{
	cv::Mat src = imread("C:\\Users\\26961\\Desktop\\images\\dog.jpg");
	if (src.empty()) {
		cout << "图片未打开" << endl;
		return -1;
	}
	QuickDemo obj;
	obj.tracking_bar_demo(src);

	//阻塞等待
	waitKey(0);

	//销毁窗口对象
	destroyAllWindows();
	return 0;

}

opencv入门 二_第1张图片

滚动条程序通过参数传递


void on_track(int lightness,void* Matobj) 
{
	//取出Mat对象,做加法运算
	Mat src = (*(Mat*)Matobj).clone();
	Mat dst = Mat::zeros(src.size(), src.type());
	Mat m = static_cast<Mat>(Scalar(lightness, lightness, lightness));
	add(src, m, dst);
	imshow("亮度调整", dst);
}

void QuickDemo::tracking_bar_demo(Mat& image)
{
	//指定主窗口
	namedWindow("亮度调整", WINDOW_AUTOSIZE);
	Mat dst = Mat::zeros(image.size(), image.type());
	Mat m = Mat::zeros(image.size(), image.type());
	Mat src = image.clone();

	int max_value = 100;
	int lightness = 50;
	createTrackbar("亮度调整", "亮度调整", &lightness, max_value, on_track, 
															(Mat *)&image);
	on_track(50 ,(void *)&image);
}	

亮度跟对比度的调整

  • 亮度的调整会将整张图片的亮度进行调高
  • 对比亮度的调整虽然会将整张图片的亮度调高,但是由于一开始的差距所以导致的亮度不一致。
    opencv入门 二_第2张图片

对比度的调整


void on_contrast(int lightness, void* Matobj)
{
	//取出Mat对象,做加法运算
	Mat src = (*(Mat*)Matobj).clone();
	Mat dst = Mat::zeros(src.size(), src.type());
	Mat m = Mat::zeros(src.size(), src.type());
	double contrast = lightness / 100.0;
	addWeighted(src, contrast, m, 0.0, 0, dst);
	imshow("亮度调整", dst);
}

void QuickDemo::tracking_bar_demo(Mat& image)
{
	//指定主窗口
	namedWindow("亮度调整", WINDOW_AUTOSIZE);
	Mat dst = Mat::zeros(image.size(), image.type());
	Mat m = Mat::zeros(image.size(), image.type());
	Mat src = image.clone();

	int contrast_value = 50;
	

	createTrackbar("对比度调整", "亮度调整", &contrast_value, 200, on_contrast,
															(void*)&image);
	on_contrast(50, &image);
}	

键盘响应操作

键盘上一些常用的键盘键值表:

opencv入门 二_第3张图片

void QuickDemo::Key_demo(Mat& image) 
{
	while (true)
	{
		int c = waitKey(100);
		if (c == 27) {
			break;
		}
		if (c == 49) {	
			std::cout << "你输入的是1" << std::endl;
		}
		if (c == 50) {
			std::cout << "你输入的是2" << std::endl;
		}
		if (c == 51) {
			std::cout << "你输入的是3" << std::endl;
		}
	}
}

waitKey会等待用户到键盘按下,之后会收到一个值,在判断之后显示对应的内容,这里主要是演示通过opencv接口和键盘之间的交互,为了方便后面通过键盘给图片改变颜色做铺垫。

opencv入门 二_第4张图片
输入窗口按下按钮后,对应的输出窗口可以获取一个值,接下来可以通过按件来控制需要生成什么样的图片了。

如何通过键盘的按键生成色彩不同的图片呢?

void QuickDemo::Key_demo(Mat& image) 
{
	Mat hsv, gray;  //彩色图和灰色图
	Mat dst = Mat::zeros(image.size(), image.type());
	while (true)
	{
		int c = waitKey(100);
		if (c == 27) {
			break;
		}
		if (c == 49) {//1号键灰色
			cvtColor(image, gray, COLOR_BGR2GRAY);
			imshow("灰色", gray);
		}
		if (c == 50) {//2号键彩色
			cvtColor(image, hsv, COLOR_RGB2HSV);
			imshow("hsv", hsv);
		}
		if (c == 51) {	//3号键自定义调色
			std::cout << "请输入色彩值" << std::endl;
			int x, y, z;
			std::cin >> x >> y >> z;  //对应B、G、R的值
			dst = static_cast<Mat>(Scalar(x, y, z));
			add(image, dst, dst);
			imshow("自定义调色", dst);
		}
	}
}

颜色表

这里列举opencv自带的颜色表,可以通过搭配颜色表中的配色方案,完成image对象的调色处理,最终可以选择保存该图片

void QuickDemo::set_color_style(Mat &image)
{
	//定义颜色表
	static int colormap[] = {
		COLORMAP_AUTUMN,
		COLORMAP_BONE,
		COLORMAP_JET,
		COLORMAP_WINTER,
		COLORMAP_RAINBOW,
		COLORMAP_OCEAN,
		COLORMAP_SUMMER,
		COLORMAP_SPRING,
		COLORMAP_COOL,
		COLORMAP_PINK,
		COLORMAP_HOT,
		COLORMAP_PARULA,
		COLORMAP_MAGMA,
		COLORMAP_INFERNO,
		COLORMAP_PLASMA,
		COLORMAP_VIRIDIS,
		COLORMAP_CIVIDIS,
		COLORMAP_TWILIGHT,
		COLORMAP_TWILIGHT_SHIFTED,
	};


	int len = sizeof(colormap) / sizeof(colormap[0]);
	//通过遍历颜色表的方式,获取applyColorMap处理后每一张具有特色的图片
	Mat dst = Mat::zeros(image.size(), image.type());
	int index = 0;
	while (true) {
		int x = waitKey(100);
		if (x == 27)	//27是ESC键的键值。
			break;

		applyColorMap(image, dst, colormap[(index++) % len]);
		imshow("自由图片播放", dst);

		if (x == 83) { //保存该图片, 83是大写S的键值
			//拼接路径
			std::string path = "C:\\Users\\26961\\Desktop\\images\\";
			std::string str(std::to_string(index) + ".jpg");
			path.append(str);
		
			std::cout << "保存图片"  << path << std::endl;
			//将图片写入路径中。
			imwrite(path, dst);
		}
		
	}
}

opencv入门 二_第5张图片

图像像素的逻辑操作

Rect(int x, int y, int width, int height);

该函数的四个参数(x , y) 表示左上角的坐标,width表示需要绘制的矩形的宽,height表示需要绘制矩形的高度。

rectangle(matobj, rect(x, y, width, height), Scalar(G, B, R), -1, LINE_8, 0);
// Mat对象     绘制矩形的大小  		色彩		第四个参数 < 0表示填充, 大于0表示绘制线宽
//	由于第四个参数选用的是-1,  所以当第五个参数选用的是LINE_8的时候会将周围的8个像素点拿来填充

填充矩形

void QuickDemo::bitwise_demo(Mat& image) 
{
	
	Mat m1 = Mat::zeros(Size(200, 200), CV_8UC3);
	Mat m2 = Mat::zeros(Size(200, 200), CV_8UC3);
	
	//填充 80 * 80的黄色矩形 和蓝色矩形
	rectangle(m1, Rect(100, 100, 80 , 80), Scalar(255, 255, 0), -1, LINE_8, 0);
	rectangle(m2, Rect(0, 0, 80, 80), Scalar(0, 255, 255), -1, LINE_8, 0);
	
	
	
	imshow("m1", m1);
	imshow("m2", m2);
}

opencv入门 二_第6张图片

绘制矩形只需要将rectangle的第三个参数改到大于0就行。


void QuickDemo::bitwise_demo(Mat& image) 
{
	
	Mat m1 = Mat::zeros(Size(200, 200), CV_8UC3);
	Mat m2 = Mat::zeros(Size(200, 200), CV_8UC3);


	//绘制 80 * 80的黄色矩形 和蓝色矩形
	//
	rectangle(m1, Rect(100, 100, 80 , 80), Scalar(255, 255, 0), 2, LINE_8, 0);
	rectangle(m2, Rect(0, 0, 80, 80), Scalar(0, 255, 255), 2, LINE_AA, 0);

	imshow("m1", m1);
	imshow("m2", m2);
}

可以看出明显的区别绘制的矩形中间是属于空心的

opencv入门 二_第7张图片

位操作

bitwise_and 按位与操作

void QuickDemo::bitwise_demo(Mat& image) 
{
	Mat m1 = Mat::zeros(Size(200, 200), CV_8UC3);
	Mat m2 = Mat::zeros(Size(200, 200), CV_8UC3);


	//填充 80 * 80的黄色矩形 和蓝色矩形
	rectangle(m1, Rect(100, 100, 80 , 80), Scalar(255, 255, 0), -1, LINE_8, 0);
	rectangle(m2, Rect(150, 150, 80, 80), Scalar(0, 255, 255), -1, LINE_8, 0);

	imshow("m1", m1);
	imshow("m2", m2);

	//Mat对象位运算
	Mat dst = Mat::zeros(Size(200, 200), CV_8UC3);
	bitwise_and(m1, m2, dst);

	imshow("按位与操作", dst);
}

m1 对象和m2对象按位与之后会得到dst对象, 这就是按位与之后的结果。

opencv入门 二_第8张图片

像素点的按位或操作 bitwise_or

void QuickDemo::bitwise_demo(Mat& image) 
{
	Mat m1 = Mat::zeros(Size(200, 200), CV_8UC3);
	Mat m2 = Mat::zeros(Size(200, 200), CV_8UC3);


	//填充 80 * 80的黄色矩形 和蓝色矩形
	rectangle(m1, Rect(100, 100, 80 , 80), Scalar(255, 255, 0), -1, LINE_8, 0);
	rectangle(m2, Rect(150, 150, 80, 80), Scalar(0, 255, 255), -1, LINE_8, 0);

	imshow("m1", m1);
	imshow("m2", m2);

	//Mat对象位运算
	Mat dst = Mat::zeros(Size(200, 200), CV_8UC3);
	bitwise_or(m1, m2, dst);

	imshow("按位与操作", dst);
}

opencv入门 二_第9张图片

bitwise_not 按位取反操作


void QuickDemo::bitwise_demo(Mat& image) 
{
	Mat m1 = Mat::zeros(Size(200, 200), CV_8UC3);
	Mat m2 = Mat::zeros(Size(200, 200), CV_8UC3);


	//填充 80 * 80的黄色矩形 和蓝色矩形
	rectangle(m1, Rect(100, 100, 80 , 80), Scalar(255, 255, 0), -1, LINE_8, 0);
	rectangle(m2, Rect(150, 150, 80, 80), Scalar(0, 255, 255), -1, LINE_8, 0);

	imshow("m1", m1);
	imshow("m2", m2);

	//Mat对象位运算
	Mat dst = Mat::zeros(Size(200, 200), CV_8UC3);
	bitwise_not(m1 , dst);
	
	imshow("按位与操作", dst);
}

m1对象的取反结果就是dst,可以看出m1的背景色是黑色而取反之后的结果确是白色,m1的矩形是蓝色,取反后的矩形是红色。

opencv入门 二_第10张图片

bitwise_xor按位异或操作

void QuickDemo::bitwise_demo(Mat& image) 
{
	Mat m1 = Mat::zeros(Size(200, 200), CV_8UC3);
	Mat m2 = Mat::zeros(Size(200, 200), CV_8UC3);


	//填充 80 * 80的黄色矩形 和蓝色矩形
	rectangle(m1, Rect(100, 100, 80 , 80), Scalar(255, 255, 0), -1, LINE_8, 0);
	rectangle(m2, Rect(150, 150, 80, 80), Scalar(0, 255, 255), -1, LINE_8, 0);

	imshow("m1", m1);
	imshow("m2", m2);

	//Mat对象位运算
	Mat dst = Mat::zeros(Size(200, 200), CV_8UC3);
	bitwise_xor(m1, m2, dst);
	
	imshow("按位与操作", dst);
}

蓝色和黄色相同的部分会被直接异或成紫色,而不同的部分则会继续保留这就是异或操作

opencv入门 二_第11张图片

你可能感兴趣的:(opencv,opencv,计算机视觉,人工智能)