OpenCV区域图像ROI和整体局部图像混合.docx
《OpenCV区域图像ROI和整体局部图像混合.docx》由会员分享,可在线阅读,更多相关《OpenCV区域图像ROI和整体局部图像混合.docx(14页珍藏版)》请在冰豆网上搜索。
OpenCV区域图像ROI和整体局部图像混合
感兴趣区域:
ROI
在图像处理领域中,专业名词感兴趣的区域其实就是选取指定区域的图像。
选择指定区域
图像中提取感兴趣区域(Regionofinterest)有两种方法:
方法一:
使用构造函数
//创建宽度为320,高度为240的3通道图像
Matimg(Size(320,240),CV_8UC3);
//roi是表示img中Rect(10,10,100,100)区域的对象
Matroi(img,Rect(10,10,100,100));
方法二:
使用括号运算符
Matroi2=img(Rect(10,10,100,100));
//用括号运算符
Matroi3=img(Range(10,100),Range(10,100));
//用构造函数
Matroi4(img,Range(10,100),Range(10,100));
测试代码
cv:
:
MatsrcMat;
QStringfileName="D:
/qtProject/openCVDemo/openCVDemo/modules/openCVManager/images/1.jpg";
srcMat=cv:
:
imread(fileName.toStdString());
if(!
srcMat.data)
{
qDebug()<<__FILE__<<__LINE__<<"Failedtoloadimage:
"<return;
}
cv:
:
imshow("orginmat",srcMat);
cv:
:
MatroiMat=srcMat(cv:
:
Range(srcMat.rows/2-50,srcMat.rows/2+50),
cv:
:
Range(srcMat.cols/2-30,srcMat.cols/2+30));
cv:
:
imshow("roimat",roiMat);
cv:
:
waitKey(0);
测试效果
图像混合(整体混合)
图像混合有多种方式。
线性混合
线性混合操作是一种典型的二元(两个输入)的像素操作,它的理论公式如下:
G(x)=(1-a)F1(x)+aF2(x)
a代表透明度的值(0.0~1.0)对两幅图像(F1和F2)活两段视频产生时间上的画面叠化效果,前面页面切换至后面页面的一个切换过程。
线性混合过程主要使用addWeighted函数。
计算数组加权和:
addWeighted()函数
这个函数的作用是计算两个mat的加权和,当然读者可以自己遍历像素计算。
该函数的原型如下:
CV_EXPORTS_WvoidaddWeighted(InputArraysrc1,
doublealpha,
InputArraysrc2,
doublebeta,
doublegamma,
OutputArraydst,
intdtype=-1);
参数一:
输入图像1,mat类型
参数二:
alpha值,表示图像1的权重
参数三:
输入图像2,mat类型
参数四:
beta值,表示图像2的权重
参数五:
gamma值,一个加到权重总和上的标量值
参数六:
输出图像dst,mat类型,它与输入的两个mat尺寸和通道相同
参数七:
dtype,输出陈列的可选深度,默认值-1,当两个输入数组具有相同的深度时,这个参数设置为-1(默认值),即等同于src1.depth()。
以上函数的计算公式如下:
dst=src1[I]*alpha+src2[I]*beta+gamma;
其中I为元素位置的索引值,当遇到多通道mat的时候,每个通道都需要独立的进行处理。
注意:
当输出mat的深度为CV_32S时,这个函数不使用,会导致内存溢出或者算出的结果错误。
测试代码
//测试线性混合:
正向与x轴翻转后的线性混合
cv:
:
Matmat1;
cv:
:
Matmat2;
cv:
:
Matmat3;
QStringfileName1="D:
/qtProject/openCVDemo/openCVDemo/modules/openCVManager/images/1.jpg";
QStringfileName2="D:
/qtProject/openCVDemo/openCVDemo/modules/openCVManager/images/1.bmp";
mat1=cv:
:
imread(fileName1.toStdString());
mat2=cv:
:
imread(fileName2.toStdString());
if(!
mat1.data||!
mat2.data)
{
qDebug()<<__FILE__<<__LINE__
<<"Failedtoloadimage:
"<return;
}
//对mat2进行缩放,缩放至mat1的大小,否则会报错
cv:
:
resize(mat2,mat2,cv:
:
Size(mat1.cols,mat1.rows));
//然后进行混合
doublea=0.0;
while(true)
{
cv:
:
addWeighted(mat1,a,mat2,(1.0-a),0.0,mat3);
cv:
:
imshow("mat3",mat3);
intkey=cv:
:
waitKey(0);
if(key==27)
{
break;
}elseif(key=='1')
{
a+=0.05;
if(a>=1.0)
{
a=1.0;
}
}elseif(key=='2')
{
a-=0.05;
if(a<0.0)
{
a=0.0;
}
}
}
测试效果
图像混合(局部混合)
原理和方法参照图像混合(整体混合)。
局部混合可以理解对感兴趣的区域进行混合,这里特别要注意一下:
使用mat1=mat2,其实mat1是mat2的副本(同一段数据);
使用mat1=mat2(roi),其实mat1是mat2上roi区域的副本(同一段数据);
使用mat1=mat2.clone(),mat1才是mat2的拷贝副本(两段相同数据);
使用mat1=mat2(roi).clone(),mat1才是mat2上roi区域的的拷贝副本(两段相同数据);
测试代码
//测试线性混合:
正向与x轴翻转后的线性混合
cv:
:
Matmat1;
cv:
:
Matmat2;
cv:
:
Matmat3;
QStringfileName1="D:
/qtProject/openCVDemo/openCVDemo/modules/openCVManager/images/1.jpg";
QStringfileName2="D:
/qtProject/openCVDemo/openCVDemo/modules/openCVManager/images/1.bmp";
mat1=cv:
:
imread(fileName1.toStdString());
mat2=cv:
:
imread(fileName2.toStdString());
if(!
mat1.data||!
mat2.data)
{
qDebug()<<__FILE__<<__LINE__
<<"Failedtoloadimage:
"<return;
}
//对mat2进行缩放,缩放至mat1的1/4的大小
cv:
:
resize(mat2,mat2,cv:
:
Size(mat1.cols/2,mat1.rows/2));
doublea=0.0;
while(true)
{
//mat4只是mat1的副本
//cv:
:
Matmat4=mat1;
cv:
:
Matmat4=mat1.clone();
qDebug()<<__FILE__<<__LINE__
<<<<cv:
:
Matmat5=mat4(cv:
:
Range(mat1.rows/2-mat1.rows/4,mat1.rows/2+mat1.rows/4),
cv:
:
Range(mat1.cols/2-mat1.cols/4,mat1.cols/2+mat1.cols/4));
qDebug()<<__FILE__<<__LINE__;
cv:
:
addWeighted(mat5,a,mat2,(1.0-a),0.0,mat5);
qDebug()<<__FILE__<<__LINE__;
cv:
:
imshow("mat4",mat4);
intkey=cv:
:
waitKey(0);
if(key==27)
{
break;
}elseif(key=='1')
{
a+=0.05;
if(a>=1.0)
{
a=1.0;
}
}elseif(key=='2')
{
a-=0.05;
if(a<0.0)
{
a=0.0;
}
}
}
测试效果
Demo源码
voidOpenCVManager:
:
testROIAndBlend()
{
#defineTEST_ROI(0)//roi
#defineTEST_BLEND(0)//图像加权混合(全部区域)
#defineTEST_BLEND_ROI
(1)//图像加权混合(roi区域)
#ifTEST_ROI
//测试提取
cv:
:
MatsrcMat;
QStringfileName="D:
/qtProject/openCVDemo/openCVDemo/modules/openCVManager/images/1.jpg";
srcMat=cv:
:
imread(fileName.toStdString());
if(!
srcMat.data)
{
qDebug()<<__FILE__<<__LINE__<<"Failedtoloadimage:
"<return;
}
cv:
:
imshow("orginmat",srcMat);
cv:
:
MatroiMat=srcMat(cv:
:
Range(srcMat.rows/2-50,srcMat.rows/2+50),
cv:
:
Range(srcMat.cols/2-30,srcMat.cols/2+30));
cv:
:
imshow("roimat",roiMat);
cv:
:
waitKey(0);
#endif
#ifTEST_BLEND
//测试线性混合:
正向与x轴翻转后的线性混合
cv:
:
Matmat1;
cv:
:
Matmat2;
cv:
:
Matmat3;
QStringfileName1="D:
/qtProject/openCVDemo/openCVDemo/modules/openCVManager/images/1.jpg";
QStringfileName2="D:
/qtProject/openCVDemo/openCVDemo/modules/openCVManager/images/1.bmp";
mat1=cv:
:
imread(fileName1.toStdString());
mat2=cv:
:
imread(fileName2.toStdString());
if(!
mat1.data||!
mat2.data)
{
qDebug()<<__FILE__<<__LINE__
<<"Failedtoloadimage:
"<return;
}
//对mat2进行缩放,缩放至mat1的大小,否则会报错
cv:
:
resize(mat2,mat2,cv:
:
Size(mat1.cols,mat1.rows));
//然后进行混合
doublea=0.0;
while(true)
{
cv:
:
addWeighted(mat1,a,mat2,(1.0-a),0.0,mat3);
cv:
:
imshow("mat3",mat3);
intkey=cv:
:
waitKey(0);
if(key==27)
{
break;
}elseif(key=='1')
{
a+=0.05;
if(a>=1.0)
{
a=1.0;
}
}elseif(key=='2')
{
a-=0.05;
if(a<0.0)
{
a=0.0;
}
}
}
#endif
#ifTEST_BLEND_ROI
//测试线性混合:
正向与x轴翻转后的线性混合
cv:
:
Matmat1;
cv:
:
Matmat2;
cv:
:
Matmat3;
QStringfileName1="D:
/qtProject/openCVDemo/openCVDemo/modules/openCVManager/images/1.jpg";
QStringfileName2="D:
/qtProject/openCVDemo/openCVDemo/modules/openCVManager/images/1.bmp";
mat1=cv:
:
imread(fileName1.toStdString());
mat2=cv:
:
imread(fileName2.toStdString());
if(!
mat1.data||!
mat2.data)
{
qDebug()<<__FILE__<<__LINE__
<<"Failedtoloadimage:
"<return;
}
//对mat2进行缩放,缩放至mat1的1/4的大小
cv:
:
resize(mat2,mat2,cv:
:
Size(mat1.cols/2,mat1.rows/2));
doublea=0.0;
while(true)
{
//mat4只是mat1的副本
//cv:
:
Matmat4=mat1;
cv:
:
Matmat4=mat1.clone();
qDebug()<<__FILE__<<__LINE__
<<<<cv:
:
Matmat5=mat4(cv:
:
Range(mat1.rows/2-mat1.rows/4,mat1.rows/2+mat1.rows/4),
cv:
:
Range(mat1.cols/2-mat1.cols/4,mat1.cols/2+mat1.cols/4));
qDebug()<<__FILE__<<__LINE__;
cv:
:
addWeighted(mat5,a,mat2,(1.0-a),0.0,mat5);
qDebug()<<__FILE__<<__LINE__;
cv:
:
imshow("mat4",mat4);
intkey=cv:
:
waitKey(0);
if(key==27)
{
break;
}elseif(key=='1')
{
a+=0.05;
if(a>=1.0)
{
a=1.0;
}
}elseif(key=='2')
{
a-=0.05;
if(a<0.0)
{
a=0.0;
}
}
}
#endif
}