本例是在运行毛星云编著的《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;

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

本例是在运行毛星云编著的《OpenCV3编程入门》书籍中的示例代码(P74 滑动条的创建和使用)时发现的报错问题,记录错误类型和解决办法,以供同样初学opencv并遇到此类问题的朋友参考。如果直接使用书籍配套代码和图片资源,可能不会报错,但是我是使用自己下载的图片进行演示,然后发现一直不能成功。报错信息:OpenCV Error: Sizes of input arguments do not match (The operation is neither ‘array op array’ (whe
在利用cv自带的加减乘除对两张图片像素进行操作时,因为其运算原理是通过获取两张(一次只能是两张)图片的同一个位置的色素值来实现运算,所以必须保证两张图片的shape相同。不然会出现以下报错: error: (-209: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).
cv2.bitwise_and() error: (-209:Sizes of input arguments do not match) The operation is neither 'array op array' (where arrays have the same size and type), nor 'array op scalar', nor 'scalar op array' in function 'cv::bin src = cv.imread("dataset/train/bees/1.png") cv.namedWindow("input", cv.WINDOW_AUTOSIZE) cv.imshow("input", src) h, w = src.shape[:2] # image.shape属性是一个tuple元组(高,宽,位深) # img.shape[:2] 取彩色图片的
项目中的一个小功能,需要实现视频特定区域的背景替换,遂写下这样一个函数:void bgReplace(Mat& dst, Mat&bg, Rect rec) assert(dst.size()==bg.size()); assert(dst.depth() == bg.depth()); dst(rec) = bg(rec).clone();//可深可浅 }功能,用rec
问题原因: You are probably working outside of the image dimensions. Does any of the values you pass to the cvSetImageROI function lay outside the image boudaries? 图像ROI区域超过了图像的尺寸,即roi.x + roi.width &gt...
图像相加的用途: 1.消除噪声:由于图像各点的采集噪声是互不相关的,且噪声具有零均值的统计特性,因此可以对图像进行多次采集形成多副图像,然后将这多副图像相加再取平均值,就可以实现噪点的消除 2.图像叠.. 今天在使用opencv中的bitwise_and函数进行图像“与”操作的时候遇到了如下的问题: 下面是我的源代码: saliency = psal.get_saliency_rbd(image).astype('uint8') ori_mask = cv2.imread(mask, 0) result = cv2.bitwise_and(ori_mask, saliency) 下面是暴...