最近,Boss需要我研究OpenCV,实现用鼠标修改图片的透明度,
具体情况是:
两张图片贴合在一起,其中一张图片a的透明度是1(完全不透明),另一张图片b的透明度是0(完全透明),鼠标点击划过的地方,将a的透明度修改为0,b的透明度修改为1,
下面的程序就是用于完成这个过程。
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;
#define WINDOW_NAME "【演示窗口】"
#define R 10
void on_MouseHandle(int event, int x, int y, int flags, void* param);
bool g_bDrawingBox = false;//是否进行绘制
Mat image;
Mat image2;
Mat imageROI; // 定义一个Mat类型,用于存放,图像的ROI
Mat tem_imageROI;
int main( )
{
//载入图片
image = imread("images/1559.jpg");
image2 = imread("images/1558.jpg");
imageROI= image(Rect(0,0,image2.cols,image2.rows));
// 将image2加到原图上
addWeighted(imageROI,1.0,image2,0.0,0.,imageROI);
//显示结果
namedWindow(WINDOW_NAME);
setMouseCallback(WINDOW_NAME,on_MouseHandle,(void*)&image);
//程序主循环,当进行绘制的标识符为真时,进行绘制
while(1)
{
imshow( WINDOW_NAME, image );
if( waitKey( 10 ) == 27 ) break;//按下ESC键,程序退出
}
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:
{
if( g_bDrawingBox )
{
//根据x,y的位置动态修改区域大小
int m = R;
if(x-R<=0 || y-R<=0 || x+R>=image.cols || y+R>=image.rows){
if(x-R*0.5<=0 || y-R*0.5<=0 || x+R*0.5>=image.cols || y+R*0.5>=image.rows){
if(x-R*0.25<=0 || y-R*0.25<=0 || x+R*0.25>=image.cols || y+R*0.25>=image.rows){
x = 0;
y = 0;
m = 0;
}else{
m = R*0.25;
}
}else{
m = R*0.5;
}
}else{
m = R;
}
tem_imageROI = image(Rect(x-m,y-m,2*m,2*m));
addWeighted(tem_imageROI,0.0,image2(Rect(x-m,y-m,2*m,2*m)),1.0,0.,tem_imageROI);
}
}
break;
//左键按下消息
case EVENT_LBUTTONDOWN:
{
g_bDrawingBox = true;
}
break;
//左键抬起消息
case EVENT_LBUTTONUP:
{
g_bDrawingBox = false;//置标识符为false
}
break;
}
}
效果图是这样的: