3.1.9作为开始入门的第一个案例,在配置好C++环境后(Visual Studio2017)尝试载入图片和图片融合操作,然而按照原书代码以及网上下载下的案例资源编译后一直出错,提示内存溢出。
以下为源代码:
#include "stdafx.h"
#include
#include
using namespace cv;
int main()
{
//-----------------------------------【一、图像的载入和显示】---------------------------------
// 描述:以下三行代码用于完成图像的载入和显示
//--------------------------------------------------------------------------------------------------
Mat girl = imread("girl.jpg"); //载入图像到Mat
namedWindow("【1】动漫图"); //创建一个名为 "【1】动漫图"的窗口
imshow("【1】动漫图", girl);//显示名为 "【1】动漫图"的窗口
//-----------------------------------【二、初级图像混合】--------------------------------------
// 描述:二、初级图像混合
//--------------------------------------------------------------------------------------------------
//载入图片
Mat image = imread("dota.jpg", 199);
Mat logo = imread("dota_logo.jpg");
//载入后先显示
namedWindow("【2】原画图");
imshow("【2】原画图", image);
namedWindow("【3】logo图");
imshow("【3】logo图", logo);
// 定义一个Mat类型,用于存放,图像的ROI
Mat imageROI;
//方法一
imageROI = image(Rect(800,350,logo.cols,logo.rows));
//方法二
//imageROI= image(Range(350,550),Range(800,1000));
// 将logo加到原图上
addWeighted(imageROI, 0.5, logo, 0.3, 0., imageROI);
//显示结果
namedWindow("【4】原画+logo图");
imshow("【4】原画+logo图", image);
//-----------------------------------【三、图像的输出】--------------------------------------
// 描述:将一个Mat图像输出到图像文件
//-----------------------------------------------------------------------------------------------
//输出一张jpg图片到工程目录下
imwrite("由imwrite生成的图片.jpg", image);
waitKey();
return 0;
}
百度查找后应该是有以下几种可能:
1、代码敲错。后反复核对,设置直接拷入网上下载的示例代码,依然报错;
2、opencv_world300d.lib与opencv_world300.lib配置不正确,一个适用于Debug一个适用于Release,不能混用,但是应该还不涉及到这个层面;
3、图片大小不匹配。也就是图片的尺寸计算有误,示例中使用的图片尺寸为:
原图:dota.jpg——1024×576,配图:dota_logo.jpg——200×200。
设置融合位置为:左上角起点坐标(800,350),这样不会超出原图画面大小。但是如果选取的两张图片大小不合适而超出范围,例如:
原图:dota.jpg——800×800,配图:dota_logo.jpg——350×350。
这样就会导致放置以后右下角坐标为:800+350=1150,800+350=1150,即(1150,1150),显然超出了原图范围,因而报错。
综上,最可能的错误应该是第三个,尤其在这一句:
imageROI = image(Rect(800,350,logo.cols,logo.rows));
因此针对此开始排查。
1、检查图片放置路径。没问题。
2、图片命名是否有误。没问题。
3、核查图片大小。按上面的方式核算,没问题。
4、将image(Rect(800,350,logo.cols,logo.rows))一句中数值进行修改,但是取(0,0,200,200)、(800,350,200,200)、(0,0,logo.cols,logo.rows)、(800,350,20,20)都出错,因此应该还有更深层次的原因。
5、是否在下面的操作函数中出错,并非imageRIO这句的错误。将这句以下的代码全部删去,依然报错,因此可以确定错因就在这行及以上代码中。
6、前面的代码中有一句为imageRIO的定义语句,即:
Mat image = imread("dota.jpg", 199);
尝试修改“199”为“1”。编译通过。
异常解决!
但是错因依然令人困扰:
按原书中讲解,取“1999”和“1”是一样的,因而思考是否只要为除负值、“0”、“2”、“4”等预先定义过的正值就可以使用,然而在前面尝试编译一次通过后,再取“199”反而不出异常了,因此这里依然匪夷所思,有待后续加深学习了解以后再思考这个小问题了。