opencv图像混合报错问题

本例是在运行毛星云编著的《OpenCV3编程入门》书籍中的示例代码(P74 滑动条的创建和使用)时发现的报错问题,记录错误类型和解决办法,以供同样初学opencv并遇到此类问题的朋友参考。
如果直接使用书籍配套代码和图片资源,可能不会报错,但是我是使用自己下载的图片进行演示,然后发现一直不能成功。
报错信息:

  1. OpenCV Error: Sizes of input arguments do not match (The operation is neither ‘array op array’ (where arrays have the same size and the same number of channels), nor ‘array op scalar’, nor ‘scalar op array’) in cv::arithm_op, file …\opencv\modules\core\src\arithm.cpp, line 1287
  2. 0x76F733D2处(位于TRACKBAR.exe中)有未经处理的异常:Microsoft C++异常:cv::Exception,位于内存位置0x004EDCAC处。

书籍源码如下:

#include<opencv2/opencv.hpp>
#include"opencv2/highgui/highgui.hpp"
using namespace cv;
#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值相对于最大值的比例
	g_dAlphaValue = (double)g_nAlphaValueSlider / g_nMaxAlphaValue;
	//则beta值为1减去alpha值
	g_dBetaValue = (1 - g_dAlphaValue);
    //根据alpha和beta值进行线性混合
	addWeighted(g_srcImage1, g_dAlphaValue, g_srcImage2, g_dBetaValue, 0.0, g_dstImage);
	//显示效果图
	imshow(WINDOW_NAME, g_dstImage);
}

//主函数
int main()
{
    //加载图像(两图像尺寸需相同)
	g_srcImage1 = imread("1.jpg");
	g_srcImage2 = imread("2.jpg");
	if (!g_srcImage1.data)
	{
		printf("第一张读取错误\n");
		return -1;
	}
	if (!g_srcImage2.data)
	{
		printf("第二张读取错误\n");
		return -1;
	}
	//设置滑动条初始值为70
	g_nAlphaValueSlider = 70;
	//创建窗体
	namedWindow(WINDOW_NAME, 1);
	//在创建的窗体中创建一个滑动条控件
	char TrackbarName[50];
	sprintf(TrackbarName, "透明度%d", g_nMaxAlphaValue);
	createTrackbar(TrackbarName, WINDOW_NAME, &g_nAlphaValueSlider, g_nMaxAlphaValue, on_Trackbar);
	//结果在回调函数中显示
	on_Trackbar(g_nAlphaValueSlider, 0);
	waitKey(0);
	return 0;

}

自行下载两张图片后,改名分别为1和2,然后注意放在和此.cpp文件放在同一路径下,否则读取图片时需要提供完整的图片存放路径。运行后产生如下错误:
在这里插入图片描述

在这里插入图片描述
点击【继续】也可以出现两张图片重叠的效果图,但是会发现无法拖动滑动条,一拖动就又会弹出上面的报错窗口。而且,当把透明度设置为0时,发现并没有使得第二张图完全显示,反而变成了全灰。出现这一系列的原因在于:

两张图片像素尺寸不匹配,需要自行改变两张图片的像素尺寸使其一致。

在这里插入图片描述

OpenCV Error: Sizes of input arguments do not match (The operation is neither 'array op array' (where arrays have the same size and the same number of channels), nor 'array op scalar', nor 'scalar op array') in cv::arithm_op, file ..\..\..\..\opencv\modules\core\src\arithm.cpp, line 1287

解决办法:

改变图片像素尺寸的方式有很多,比如可以通过PS技术进行改变,但是opencv提供了各种函数接口用来处理图像,我们可以使用resize()函数来改变。
resize是opencv库中的一个函数,其函数功能是缩小或者放大图像至某一个大小。
函数原型为:

void resize( InputArray src, OutputArray dst,
                          Size(width,height), double fx = 0, double fy = 0,
                          int interpolation = INTER_LINEAR );

其中src为待改变大小的图像变量名;dst为改变大小之后的图像变量名;Size(width,height)为图像改变成为的指定像素大小;fx是width方向的缩放比例,如果它是0,那么它就会按照(double)dsize.width/src.cols来计算;fy是height方向的缩放比例,如果它是0,那么它就会按照(double)dsize.height/src.rows来计算;图像缩放之后需对像素要进行重新计算,interpolation参数来指定重新计算像素的方式,不指定时默认使用双线性插值,即INTER_LINEAR。
在读入图片后我们加上这个函数,就可以顺利运行,添加修改语句为:

	Mat img1 = imread("1.jpg");//定义两个Mat类型的存放读入图片的变量
	Mat img2 = imread("2.jpg");
	resize(img1, img1, Size(550, 320), 0, 0, CV_INTER_LINEAR);//改变读入图片的尺寸,使得两张融合图片的像素一致 否则融合会报错
	resize(img2, img2, Size(550, 320), 0, 0, CV_INTER_LINEAR);
	g_srcImage1 = img1;
	g_srcImage2 = img2;

需要注意:图片究竟尺寸改成多大还需看一下图片原始信息,改变后的像素值尽量不要和原图有过大出入,比如原图是30 * 20像素的图片,我们改成550 * 320效果可能就不太好。原始图片像素查询方法为:选中图片并右键,选择【属性】,再选择【详细信息】,就可以看到了。
在这里插入图片描述

修改后的完整代码:

#include<opencv2/opencv.hpp>
#include<opencv2/highgui/highgui.hpp>
using namespace cv;
#define WINDOW_NAME "线性混合"

const int g_nMaxAlphaValue = 100;
int g_nAlphaValueSlider;
double g_dAlphaValue;
double g_dBetaValue;

Mat g_srcImage1;
Mat g_srcImage2;
Mat g_dstImage;

void on_Trackbar(int, void*)
{
	g_dAlphaValue = (double)g_nAlphaValueSlider / g_nMaxAlphaValue;
	g_dBetaValue = (1 - g_dAlphaValue);

	addWeighted(g_srcImage1, g_dAlphaValue, g_srcImage2, g_dBetaValue, 0.0, g_dstImage);
	imshow(WINDOW_NAME, g_dstImage);
}

int main()
{
/*修改的部分*/
//............................................................................................//
	Mat img1 = imread("1.jpg");//定义两个Mat类型的存放读入图片的变量
	Mat img2 = imread("2.jpg");
	resize(img1, img1, Size(550, 320), 0, 0, CV_INTER_LINEAR);//改变读入图片的尺寸,使得两张融合图片的像素一致 否则融合会报错
	resize(img2, img2, Size(550, 320), 0, 0, CV_INTER_LINEAR);
	g_srcImage1 = img1;
	g_srcImage2 = img2;
//...........................................................................................//
	if (!g_srcImage1.data)
	{
		printf("第一张读取错误\n");
		return -1;
	}
	if (!g_srcImage2.data)
	{
		printf("第二张读取错误\n");
		return -1;
	}
	g_nAlphaValueSlider = 70;
	namedWindow(WINDOW_NAME, 1);
	char TrackbarName[50];
	sprintf(TrackbarName, "透明度%d", g_nMaxAlphaValue);
	createTrackbar(TrackbarName, WINDOW_NAME, &g_nAlphaValueSlider, g_nMaxAlphaValue, on_Trackbar);
	on_Trackbar(g_nAlphaValueSlider, 0);
	waitKey(0);
	return 0;

}

运行结果:
在这里插入图片描述
可以看到没有任何报错弹出,此时滑动条也可以通过鼠标流畅滑动。
【这张混合后的图片还蛮好看的,有种灵魂叠加的感觉~】
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值