OpenCV(C++) 基础(二)– 滑动条与色彩通道

  • Post author:
  • Post category:其他


1.创建滑动条

// 创建滑动条
// trackbarname:滑动空间的名称;
// winname:滑动空间用于依附的图像窗口的名称;
// value:初始化阈值;
// count:滑动控件的刻度范围;
// TrackbarCallback是回调函数
createTrackbar(trackbarname, winname, value, count, TrackbarCallback onChange = 0, userdata = 0);

2.滑动条demo

// createTrackBar Demo:调整两张图的透明度
#define WIN_NAME "trackBar demo"
const int maxAlphaValue = 100; // 最大透明度值
int sliderValue;     // 滑动条当前值
double alphaValue, betaValue;
Mat img1, img2, img3;

void on_TrackBar(int, void*) { // 回调函数
	alphaValue = (double)sliderValue / maxAlphaValue;
	betaValue = 1.0 - alphaValue;
	addWeighted(img1, alphaValue, img2, betaValue, 0.0, img3); // linear mixed线性混合
	imshow(WIN_NAME, img3);
}

int main(int argc, char** argv) {
	img1 = imread("H:/CV/pic/004.jpg");
	img2 = imread("H:/CV/pic/002.jpg");
	if (!img1.data) printf("wrong img1!"); // 读取出错
	if (!img2.data) printf("wrong img2!");
	sliderValue = 70; // initial value 初始值
	namedWindow(WIN_NAME, 1);
	char TrackbarName[50];
	sprintf_s(TrackbarName, "Alpha %d", maxAlphaValue); // 发送格式化输出到 TrackbarName 所指向的字符串
	createTrackbar(TrackbarName, WIN_NAME, &sliderValue, maxAlphaValue, on_TrackBar); // 创建滑动条
	on_TrackBar(sliderValue, 0);
	waitKey(0);
	return 0;
}

3.鼠标回调函数

// setMouseCallback
// winname:窗口的名字
// onMouse:鼠标响应函数,回调函数。指定窗口里每次鼠标时间发生的时候,被调用的函数指针。 这个函数的原型应该为void on_Mouse(int event, int x, int y, int flags, void* param);
// userdate:传给回调函数的参数 
 void setMousecallback(winname, MouseCallback onMouse, userdata=0)

4.setMousecallback demo: 绘制随机彩色矩形

// draw rectangle demo
#define WIN_NAME "trackBar demo"
void on_MouseHandle(int event, int x, int y, int flags, void* param);
void drawRectangle(cv::Mat&img, cv::Rect box); //矩形绘制函数
Rect rect; // 矩形
bool drawingBox = false; // whether draw rect or not 是否绘制
// random num generator
RNG rng(12345); // 可以压缩一个64位的整数并可以得到scalar和array的随机数

int main() {
	rect = Rect(-1, -1, 0, 0); // x, y, width, height
	Mat src(600, 800, CV_8UC3), tmpImg;  // RGB 3通道: CV8UC3, define canvas
	src.copyTo(tmpImg);
	rect = Rect(-1, -1, 0, 0);
	src = Scalar::all(0); // initialization: all pixels set as 0 初始化黑色幕布
	namedWindow(WIN_NAME);
	setMouseCallback(WIN_NAME, on_MouseHandle, (void*)&src);
	while (1) {
		src.copyTo(tmpImg);
		if (drawingBox) drawRectangle(tmpImg, rect);
		imshow(WIN_NAME, tmpImg);
		if (waitKey(10) == 27)break; // push Esc to exit, Esc ASCII code is 27
	}
	return 0;	
}

void on_MouseHandle(int event, int x, int y, int flags, void* param) {
	Mat& image = *(cv::Mat*) param;
	switch (event) {
		case EVENT_MOUSEMOVE:{ // mouse move action 鼠标移动则计算矩形宽高
			if (drawingBox) {
				rect.width = x - rect.x;
				rect.height = y - rect.y;
			}
		} break;

		case EVENT_LBUTTONDOWN: { // left button down 点击左键,绘制标记drawingBox置为true
			drawingBox = true;
			rect = Rect(x, y, 0, 0); // record start point
		} break;

		case EVENT_LBUTTONUP: { // left button up 抬起左键
			drawingBox = false;
			if (rect.width < 0) { // mouse moves up will cause rect.width < 0
				rect.x += rect.width;
				rect.width *= -1;
			}
			if (rect.height < 0) { // same
				rect.y += rect.height;
				rect.height *= -1;
			}
			drawRectangle(image, rect); // 绘制矩形
		} break;
	}
}

void drawRectangle(cv::Mat& img, cv::Rect box) {
	rectangle(img, box.tl(), box.br(),  //tl: top_left, br: bottom_right,坐上和右下坐标
		Scalar(rng.uniform(0, 255),rng.uniform(0, 255), rng.uniform(0, 255))); //Scalar:颜色类,随机颜色
}

5.矩形类

Rect(x, y, width, height) // 左上角坐标x,y 长宽 width,height
Rect rect = rect1 | rect2; // union set 并集
Rect rect = rect1 & rect2; // intersection 交集
rect = rect1 + point;      // shift 平移
rect = rect1 + size;       // zoom 缩放

6.色彩空间转换

// cvtColor(src, dst, code, dstCn = 0); 原图,目标图,转换码
cvtColor(src, dst, CV_BGR2GRAY); // opencv2 RGB转灰度图
cvtColor(src, dst, COLOR_BGR2GRAY; // opencv3 RGB转灰度图

7.绘制椭圆

void drawEllipse(Mat img, double angle) { //绘制椭圆形
	int thickness = 2;
	int lineType = 8;
	ellipse(img,
		Point(WW / 2, WW / 2), // 中心点
		Size(WW / 4, WW / 16), // 外接矩形 
		angle, 0, 360,		   // 角度范围
		Scalar(255, 129, 0),   // 颜色
		thickness, lineType);  // 线宽,线型
}

8.绘制直线

line(img, start, end, Scalar(0, 0, 0), thickness, lineType); //start和end都是Point类型,thickness和lineType默认为 1和8

9.分离/合并色彩通道

Mat src = imread(“001.jpg”);
vector<Mat>channels; // 通道数组
split(src, channels); // split the channels 分离通道
imgBlueChannel = channels.at(0); // BGR: 012 蓝色通道
imgGreenChannel = channels.at(1);
imgRedChannel = channels.at(2);
merge(channels, src); // merge the channels 合并通道

10.调整亮度/对比度

//contrastValue:对比度    brightValue:亮度
for (int i = 0; i < src.rows; i++) {             // 行
	for (int j = 0; j < src.cols; j++) {     // 列
		for (int c = 0; c < 3; c++) {    // 通道
			// saturate_cast: 溢出保护,data = 0 if data<0  <==> data = 255 if data>255
			// dst.at<Vec3b>(i, j)[c]: 图像dst在c通道(i, j)处的像素值
			dst.at<Vec3b>(i, j)[c] = saturate_cast<uchar>( contrastValue * (src.at<Vec3b>(i, j)[c]) + brightValue);
		}
	}
}



版权声明:本文为francislucien2017原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。