混合图像
也就是将一个图片加到另一个图片上面。
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
using namespace std;
int main()
{
Mat image = imread("picture/10.png",199);
Mat logo = imread("picture/christ.jpg");
namedWindow("原始图像1");
imshow("原始图像1", image);
namedWindow("原始图像2");
imshow("原始图像2", logo);
Mat imageROI;
imageROI = image(Rect(100, 350, logo.cols, logo.rows));
// imageROI = image(Range(350, 350 + logo.rows), Range(800, 800 + logo.cols));
//将logo加到原始图像1上
addWeighted(imageROI, 0.5, logo, 0.3,0.0, imageROI);
namedWindow("混合后的图像是");
imshow("混合后的图像是",image);
waitKey(0);
return 0;
}
模拟滚动条
主要是利用createTrackbar()
函数创建滚动条效果。这里实现的是灰度图和原始图像的混合,用滚动条控制图像之间的转换。
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
using namespace std;
#define WINDOW_NAME "[线性混合实例]"
//声明全局变量
const int g_nMaxAlphaValue = 100; //Alpha最大值
int g_nAlphaValueSlider; //滑动条对应的值
double g_dAlphaValue;
double g_dBetaValue;
Mat g_srcImage1;
Mat g_srcImage2;
Mat g_dstImage;
//相应滚动条的回调函数
void on_Trackbar(int , void *) //必须是这种类型
{
//求档前Alpha值对应与最大值的比例
// cout<<g_nAlphaValueSlider<<endl;
g_dAlphaValue = (double)g_nAlphaValueSlider/g_nMaxAlphaValue;
g_dBetaValue = 1.0 - g_dAlphaValue;
//根据Alpha和Beta值进行线性混合
addWeighted(g_srcImage1,g_dAlphaValue,g_srcImage2,g_dBetaValue,0.0,g_dstImage);
imshow(WINDOW_NAME,g_dstImage);
}
int main(int argc,char **argv)
{
//加载两幅尺寸相同的图
g_srcImage1 = imread(argv[1]);
g_srcImage2 = imread(argv[2]);
if(!g_srcImage1.data) cout<<"读取第一负图片错误"<<endl;
if(!g_srcImage2.data) cout<<"读取第二负图错误"<<endl;
//设置滚动条的初始值为69;
g_nAlphaValueSlider = 30;
//创建窗体
namedWindow(WINDOW_NAME,1);
//在窗体中添加滚动条
char TrackbarName[50];
sprintf(TrackbarName,"透明值%d",g_nMaxAlphaValue); createTrackbar(TrackbarName,WINDOW_NAME,&g_nAlphaValueSlider,g_nMaxAlphaValue,on_Trackbar); //创建滚动条效果
int barPos = getTrackbarPos(TrackbarName,WINDOW_NAME);
cout<<"轨迹条的位置是"<<barPos<<endl;
//结果在回调函数中显示
on_Trackbar(g_nAlphaValueSlider,0);
// int barPos = getTrackbarPos(TrackbarName,WINDOW_NAME);
// cout<<"轨迹条的位置是"<<barPos<<endl;
// waitKey(0);
//按下键盘Q退出
while(1)
{
if(char (waitKey(0))=='q')
break; //注意,break只能用于循环语句中!!如果if语句外没有循环,会报错.注意这里和if和while配合使用!!
}
return 0;
}
设置鼠标事件
主要是调用了SetMouseCallback
函数,为指定的窗口设置回调函数。
#include <opencv2/opencv.hpp>
//#include <opencv2/core/bufferpool.hpp>
using namespace std;
using namespace cv;
#define WINDOW_NAME "[程序窗口]"
void on_MouseHandle(int event, int x, int y, int flags, void *parm);
void DrawRectangle(Mat &img, Rect box);
//void ShowHelpText();
Rect g_rectangle;
bool g_bDrawingBox = false; //是否进行绘制
RNG g_rng(12345);
int main()
{
g_rectangle = Rect(-1, -1, 0, 0);
Mat srcImage(600, 800, CV_8UC3), tempImage;
srcImage.copyTo(tempImage);
//g_rectangle = Rect(-1, -1, 0, 0);
srcImage = Scalar::all(0);
//设置鼠标回调函数
namedWindow(WINDOW_NAME);
setMouseCallback(WINDOW_NAME, on_MouseHandle, (void *)&srcImage);
while (1)
{
srcImage.copyTo(tempImage);
if (g_bDrawingBox)
DrawRectangle(tempImage, g_rectangle);//当进行绘制的标示符为真时,则进行绘制
imshow(WINDOW_NAME, tempImage);
if (waitKey(10) == 27) //按下ESC键,程序退出
break;
}
return 0;
}
//鼠标回调函数,根据不同鼠标事件进行不同的操作
void on_MouseHandle(int event, int x, int y, int flags, void *parm)
{
Mat &image = *(Mat *)parm;
switch (event)
{
//鼠标滚动信息
case EVENT_MOUSEMOVE:
{
if (g_bDrawingBox)
{
g_rectangle.width = x - g_rectangle.x;
g_rectangle.height = y - g_rectangle.y;
}
}
break;
case EVENT_LBUTTONDOWN: //左键按下的信息
{
g_bDrawingBox = true;
g_rectangle = Rect(x, y, 0, 0);//记录起始点
}
break;
case EVENT_LBUTTONUP: //左键抬起
{
g_bDrawingBox = false;
if (g_rectangle.width < 0) //对于宽度小于0处理
{
g_rectangle.x += g_rectangle.width;
g_rectangle.width *= -1;
}
if (g_rectangle.height < 0)
{
g_rectangle.y += g_rectangle.height;
g_rectangle.height *= -1;
}
DrawRectangle(image, g_rectangle);
}
break;
}
}
void DrawRectangle(Mat &img, Rect box) //自定义的矩形绘制函数
{
rectangle(img, box.tl(), box.br(), Scalar(g_rng.uniform(0, 255)), g_rng.uniform(0, 255),
g_rng.uniform(0, 255));//随机颜色
}