TrackBar滚动条
void Demo::tracking_bar_demo(Mat &image) {
namedWindow("亮度调整", WINDOW_AUTOSIZE);
int lightness = 50;
int max_value = 100;
createTrackbar("Value", "亮度调整", &lightness, max_value, on_track,(void*)(&image));
//trackbar窗口名称,要改变的窗口名称,要改变的值,改变的最大值,回调函数
on_track(lightness, &image);
}
在createTrackbar中设置好参数:
参数1:轨迹条名字
参数2:窗口名字
参数3:滑块初始位置
参数4:表示滑块达到最大位置的值
参数5:默认值为0,指向回调函数
参数6:默认值为0,用户传给回调函数的数据值
在回调函数中设计当滑动滑块时进行的操作
static void on_track(int light, void* tepimage) {
Mat image = *((Mat*)tepimage);
Mat dst = Mat::zeros(image.size(), image.type());
Mat m = Mat::zeros(image.size(), image.type());
Mat src = image;
m = Scalar(light, light, light);
add(src, m, dst);
imshow("亮度调整", dst);
}
例:在这里调整亮度
键盘响应操作
键盘相应其实相对来说十分简单,只需要判断输入的字符,并根据相应的字符做出对应的操作即可
void Demo::key_demo(Mat &image) {
Mat dst = Mat::zeros(image.size(),image.type());
while (true) {
char c = waitKey(200);
if (c == 27)
break;
if (c == 49) {
//#1
cvtColor(image, dst, COLOR_BGR2GRAY);
}
if (c == 50) {//#2
cvtColor(image, dst, COLOR_BGR2HSV);
}
if (c == 51) {//#3
dst = Scalar(50, 50, 50);
add(image, dst, dst);
}
imshow("键盘响应",dst);
}
}
图像像素的逻辑操作
void Demo::bitwise_demo(Mat &image) {
Mat m1 = Mat::zeros(Size(256, 256), CV_8UC3);
Mat m2 = Mat::zeros(Size(256, 256), CV_8UC3);
//绘制矩形(绘制目标,绘制坐标及大小,颜色,边框宽度)
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 dst;
bitwise_and(m1, m2, dst);//与
bitwise_not(image, dst);//非(取反)
bitwise_or(m1, m2, dst);//或
bitwise_xor(m1, m2, dst);//异或
imshow("像素位操作", dst);
}
其中and,or,xor需要三个参数,not需要两个参数
通道分离与合并
知识准备
-
一个图像的通道数是N,就表明每个像素点处有N个数,一个a×b的N通道图像,其图像矩阵实际上是b行N×a列的数字矩阵。
OpenCV中图像的通道可以是1、2、3和4。其中常见的是1通道和3通道,2通道和4通道不常见。
1通道的是灰度图。
3通道的是彩色图像,比如RGB图像。
4通道的图像是RGBA,是RGB加上一个A通道,也叫alpha通道,表示透明度。PNG图像是一种典型的4通道图像。alpha通道可以赋值0到1,或者0到255,表示透明到不透明。
2通道的图像是RGB555和RGB565。2通道图在程序处理中会用到,如傅里叶变换,可能会用到,一个通道为实数,一个通道为虚数,主要是编程方便。RGB555是16位的,2个字节,5+6+5,第一字节的前5位是R,后三位+第二字节是G,第二字节后5位是B,可见对原图像进行压缩了。
-
OpenCV中用imshow( )来显示图像,只要Mat的数据矩阵符合图像的要求,就可以用imshow来显示。超过了4通道,就不是图像了,imshow( )也显示不了。
-
mshow( )显示单通道图像时一定是灰度图,如果我们想显示红色的R分量,还是应该按三通道图像显示,只不过G和B通道要赋值成0或255.
-
通道分解用split( ),通道合成用merg( ),这俩函数都是mixchannel( )的特例。
具体应用
void Demo::channel_demo(Mat &image) {
vector<Mat> mv;
split(image, mv);
//第一个参数为输入图像,第二个参数为分解后的输出,因为有BGR三个通道,因此需要一个Mat类型的数组来存储
//imshow("B", mv[0]);
//imshow("G", mv[1]);
//imshow("R", mv[2]);
Mat dst;
mv[1] = 0;
mv[2] = 0;
merge(mv, dst);
//第一个参数为输入三个通道,同样为mat类型数组,第二个参数为合并后的输出图像
//imshow("dst", dst);
int from_to[] = { 0, 2, 1, 1, 2, 0 };//混合参数,两个一对,表示一对内的两个通道交换
mixChannels(&image,1, &dst,1, from_to,3);
//两个参数一对,第一对表示输入及输入数量,第二队表示输出及输出数量,第三对表示混合参数及混合参数有几对
imshow("dst", dst);
//制作透明图片(即加上第四通道A通道)
Mat imageA85 = Mat(image.size(), image.depth(), Scalar(85));
Mat imageRGBA85 = Mat(image.size(), CV_8UC4);
Mat in2[] = { image,imageA85 };
int from_to01[] = { 0,0, 1,1, 2,2, 3,3 };
mixChannels(in2, 2, &imageRGBA85, 1, from_to01, 4);
imshow("11111", imageRGBA85);
}
图像色彩空间转换
- 色彩空间转换cvtColor函数
- 提取指定的色彩范围区域inRange;
首先给出HSV模型的大概知识:
具体实施
void Demo::inrange_demo(Mat &image) {
Mat hsv;
cvtColor(image, hsv, COLOR_BGR2HSV);
Mat mask;
inRange(hsv, Scalar(0,0,46), Scalar(180,43,220),mask);
//输入图像,range的最小值,range的最大值,输出图像
imshow("mask", mask);
//替换
Mat back = Mat::zeros(image.size(), image.type());
back = Scalar(40, 40, 200);
bitwise_not(mask, mask);
imshow("111", mask);
image.copyTo(back, mask);
imshow("222", mask);
}
一般处理过程:将RGB图像通过cvtColor函数转换成HSV图像,对其进行处理,处理完之后再将其转换回RGB图像
图像像素值统计
void Demo::pixel_statistic_demo(Mat &image) {
vector<Mat> mv;
split(image, mv);
//要求单通道
double minv, maxv;
Point minLoc, maxLoc;
//获取最小值最大值和相应的地址
minMaxLoc(mv[0], &minv, &maxv,&minLoc, &maxLoc, Mat());
cout << minv << endl << maxv << endl;
//求取均值和方差
Mat mean, stddev;
meanStdDev(mv[0], mean, stddev);
cout << mean << endl << stddev << endl;
}