C++OpenCV利用Trackbar实现对图片的滑动阈值调节

该博客介绍了一个使用OpenCV进行图像处理的项目,包括美颜、模糊背景、调整亮度和绘制矩形相框等功能。通过创建滚动条调整参数,实现了实时预览效果。代码中使用了高斯模糊、双边滤波、调整图像大小和亮度等技术,以实现类似美颜相机的视觉效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

代码如下所:

#include <opencv2/opencv.hpp>
#include <iostream>
#include"myApi.h"

using namespace std;
using namespace cv;

Mat g_srcImg; //原图片
Mat g_beautyFgImg;  //美颜后的前景图
Mat g_vagueBeImg;  //模糊后背景图
Mat g_roiImg;  //前景和后景组合后图片
Mat g_rectImg;  //绘制矩形边框
Mat g_brightImg;  //调整亮度


// 调整模糊程度
int g_iVagueValue = 3;
int g_iVagueMaxValue = 10;

// 调整美颜程度
int g_iBeautyValue = 9;
int g_iBeautyMaxValue = 20;

// 绘制矩形,设置相框
int g_iRectValue = 5;
int g_iRectMaxValue = 30;

//调整亮度范围
int g_iBrightValue = 6;
int g_iBrightMaxValue = 20;

//调整模糊程度
void TrackbarVague(int, void*);

//调整美颜程度
void TrackbarBeauty(int, void*);

//绘制矩形调整相框
void TrackbarRect(int, void*);

//调整亮度程度
void TrackbarBright(int, void*);

//将美颜前景图调到模糊背景图层上
void SetRoi(void);

int main()
{
	g_srcImg = imread("F:\\testImage\\test2.png");
	if (!g_srcImg.data)
		return -1;
	namedWindow("img", WINDOW_FREERATIO);
	imshow("img", g_srcImg);

	/*
	功能:创建滚动条并将其附加到指定的窗口
	参数:trackbarname:创建的滚动条名称
		  winname:滚动条父窗口的名称
		  value:滚动条所在位置的值
		  count:滚动条的最大值,最小值总是0
		  onChange:指向滚动条改变位置时要调用的函数的指针(回调函数),函数的原型应该是void Foo(int, void*);
					其中第一个参数是滚动条所在的位置,第二个参数是用户数据(见下一个参数);如果回调函数传空,则不调用
					回调,但只更新滚动条值
		  userdata:按原样传递给回调的用户数据,它可以用来处理滚动条不使用全局变量事件
	返回:成功返回0
	*/

	createTrackbar("背景模糊", "img", &g_iVagueValue, g_iVagueMaxValue, TrackbarVague);
	createTrackbar("前景美颜", "img", &g_iBeautyValue, g_iBeautyMaxValue, TrackbarBeauty);
	TrackbarBeauty(0, 0);

	createTrackbar("相框宽度", "img", &g_iRectValue, g_iRectMaxValue, TrackbarRect);
	TrackbarRect(0, 0);

	createTrackbar("图片亮度", "img", &g_iBrightValue, g_iBrightMaxValue, TrackbarBright);
	TrackbarBright(0, 0);
	TrackbarVague(0, 0);
	waitKey(0);
	return 0;
}

void TrackbarVague(int, void*)
{
	//SignaX和SigmaY必须是奇数
	int iSigma = 2 * g_iVagueValue + 1;
	//利用高斯模糊做底图
	GaussianBlur(g_srcImg, g_vagueBeImg, Size(iSigma, iSigma), iSigma, iSigma);
	//全部初始化完才显示
	if (g_beautyFgImg.data && g_vagueBeImg.data)
	{
		SetRoi();
	}
}

void TrackbarBeauty(int, void*)
{
	// 利用双边模糊,实现磨皮的效果
	int iSigmaSpace = 50 + 10 * g_iBeautyValue;
	Mat tmpImg;
	bilateralFilter(g_srcImg, tmpImg, 15, iSigmaSpace, 0);

	// 再利用掩膜计算,增加图像对比度,最终实现美颜相机的效果
	Mat kernal = (Mat_<int>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
	filter2D(tmpImg, g_beautyFgImg, -1, kernal, Point(-1, -1), 0);

	// 功能:调整图像大小
	// 参数:src 源图像
	//		 dst 目标图像
	//		 dsize 输出图像大小,如果为(0, 0),则大小为(img.cols * fx, img.rows * fy)
	//		 fx x方向的缩小比例
	//		 fy y方向的缩小比例
	resize(g_beautyFgImg, g_beautyFgImg, Size(0, 0), 0.8, 0.8);

	// 全部初始化完才显示
	if (g_beautyFgImg.data && g_vagueBeImg.data)
	{
		SetRoi();
	}
}

void TrackbarRect(int, void*)
{
	if (!g_roiImg.data)
	{
		return;
	}

	// 绘制一个矩形,当做相框
	int iPosX = (g_vagueBeImg.cols - g_beautyFgImg.cols) / 2 - g_iRectValue / 2;
	int iPosY = (g_vagueBeImg.rows - g_beautyFgImg.rows) / 2 - g_iRectValue / 2;
	int iWidth = g_beautyFgImg.cols + g_iRectValue;
	int iHeight = g_beautyFgImg.rows + g_iRectValue;
	Rect rect(iPosX, iPosY, iWidth, iHeight);
	Scalar color(255, 255, 255);
	g_rectImg = g_roiImg.clone();
	rectangle(g_rectImg, rect, color, g_iRectValue);

	// 调整颜色
	TrackbarBright(g_iBrightValue, 0);
}

void TrackbarBright(int, void*)
{
	if (!g_rectImg.data)
	{
		cout << "g_rectImg is empty" << endl;
		return;
	}
	int iRows = g_rectImg.rows;
	int iCols = g_rectImg.cols;
	Mat tmpImg = Mat::zeros(g_rectImg.size(), g_rectImg.type());
	float fAlpha = 0.1 + (float)g_iBrightValue / 10.0;
	float fBeta = 30; // 增益变量

	for (int i = 0; i < iRows; i++)
	{
		for (int j = 0; j < iCols; j++)
		{
			if (g_rectImg.channels() == 1)
			{
				float f = g_rectImg.at<uchar>(i, j);
				tmpImg.at<uchar>(i, j) = saturate_cast<uchar>(f * fAlpha + fBeta);
			}
			else if (g_rectImg.channels() == 3)
			{
				float fGreen = g_rectImg.at<Vec3b>(i, j)[0];
				float fBlue = g_rectImg.at<Vec3b>(i, j)[1];
				float fRed = g_rectImg.at<Vec3b>(i, j)[2];

				tmpImg.at<Vec3b>(i, j)[0] = saturate_cast<uchar>(fGreen * fAlpha + fBeta);
				tmpImg.at<Vec3b>(i, j)[1] = saturate_cast<uchar>(fBlue * fAlpha + fBeta);
				tmpImg.at<Vec3b>(i, j)[2] = saturate_cast<uchar>(fRed * fAlpha + fBeta);
			}
		}
	}

	// 保存调整亮度后的背景图
	g_brightImg = tmpImg.clone();

	imshow("img", g_brightImg);
}


void SetRoi(void)
{
	// 设定ROI区域
	int iPosX = (g_vagueBeImg.cols - g_beautyFgImg.cols) / 2;
	int iPosY = (g_vagueBeImg.rows - g_beautyFgImg.rows) / 2;
	g_roiImg = g_vagueBeImg.clone();
	Mat imageROI = g_roiImg(Rect(iPosX, iPosY, g_beautyFgImg.cols, g_beautyFgImg.rows));
	//加载掩摸
	Mat mask;
	cvtColor(g_beautyFgImg, mask, COLOR_BGR2GRAY);
	g_beautyFgImg.copyTo(imageROI, mask);
	TrackbarRect(g_iRectValue, 0);
}

实验结果如下所示:

 

C++ 中使用 OpenCV 的 `createTrackbar` 函数可以创建滑动条调节图像的颜色通道值或其他参数。虽然无法直接用滑动条“画”出熊猫头像,但我们可以通过调整 RGB 或 HSV 等色彩空间的阈值,从一张包含熊猫图案的彩色图片中提取出黑白区域并呈现熊猫的形象。 以下是实现步骤及代码示例: --- ### 步骤说明 1. **加载原始图像** 加载一幅包含熊猫头像的彩色图片作为素材(比如 PNG 图片文件)。 2. **创建滑动条控件** 使用 `cv::createTrackbar` 动态控制阈值范围,分别对亮度、对比度或者其他特征属性进行筛选。 3. **二值化处理图像** 根据滑块返回的结果设定上下限条件来进行掩码运算得到结果图层。 4. **实时渲染效果展示** 将每次修改后的输出显示在一个独立窗口内供观察者查看变化过程。 下面提供了一个完整的小例子帮助理解整个流程: ```cpp #include <opencv2/opencv.hpp> using namespace cv; // 全局变量声明 int thresholdValue = 127; // 初始化阈值 const int maxThreshold = 255; Mat srcImage, grayImage, binaryImage; // 回调函数原型 static void on_trackbar(int, void*) { // 对灰度图像应用固定阈值得到二进制图像 .threshold(grayImage,binaryImage,Thrresholdvalue,CV_THRESH_BINARY); } int main() { // 第一步:读取源图像 srcImage = imread("panda.jpg"); // 替换为实际路径名 if(srcImage.empty()){ cout << "Could not open or find the image!" << endl; return -1; } // 转换成灰色版本副本用于后续计算 cvtColor(srcImage ,grayImage COLOR_BGR2GRAY ); // 命名为"Control Panel"的新窗口存放轨道杆组件组 namedWindow("Control Panel"); createTrackbar("Threshold:", "Control Panel",&thresholdValue,maxThreshold,on_trackbar); // 默认先运行一次初始化绘图阶段的操作 on_trackbar(thresholdValue,nullptr); while(true) { // 显示最终效果图于单独命名视窗之中 imshow("Binary Image",binaryImage); char c=(char)waitKey(20); // 添加延时避免CPU占用过高 if(c==27) { // ESC键退出循环 break; } } destroyAllWindows(); return 0; } ``` 在这个项目里,我们将学习如何借助用户界面元素改变某些视觉特性,并借此生成期望的目标轮廓形状。如果原图质量足够高的话,则很容易获得栩栩如生的大熊猫模样啦! ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AI炮灰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值