好久不用opencv,重新开始使用opencv,第一次写的程序就遇到了bug。
#include <opencv2/opencv.hpp>
#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <opencv2/nonfree/nonfree.hpp>
#include <opencv2/legacy/legacy.hpp>
#define NUM 30000
using namespace cv;
using namespace std;
int main()
{
string ImgNum;
int Index=1;
while(Index < NUM)
{
ImgNum = "1";
//int转string
stringstream ss;
string str;
ss<<Index;
ss>>str;
ImgNum = ImgNum + " (" + str +")";
ImgNum = "O:\\DP\\1124原始片\\" + ImgNum + ".bmp";
Mat image = imread("ImgNum");
if(image.data == 0)
{
printf("没有图片");
return 0;
}
imshow("image",image);
//处理算法
Mat grayimage,region,regionout;
vector<Mat> channels;
split(image,channels);
grayimage = channels[2];
imshow("gray",grayimage);
Mat regions =Mat::zeros(grayimage.size(),CV_8UC1);
threshold(grayimage,region,20,255,CV_THRESH_BINARY_INV);
Mat element0 = getStructuringElement(MORPH_RECT,Size(10,10));
erode(region,region,element0);
dilate(region,region,element0);
imshow("region",region);
vector<vector<Point>>contours;
vector<Vec4i>hierarchy;
findContours(region,contours,hierarchy,CV_RETR_LIST,CHAIN_APPROX_NONE,Point(0,0));
vector<Rect>boundRect(contours.size());
vector<vector<Point>> contours_poly(contours.size());
for(unsigned int i=0;i<(contours.size()-1);i++)
{
boundRect[i]=boundingRect(Mat(contours[i]));
if(boundRect[i].width>8 && boundRect[i].width<30)
{
drawContours(regions,contours,i,Scalar(255),-1);
}
}
imshow("regions",regions);
imshow("regions",regions);
waitKey();
Mat element = getStructuringElement(MORPH_RECT,Size(25,1));
erode(region,regionout,element);
imshow("regionout",regionout);
//
waitKey(0);
Index++;
}
return 0;
}
这里主要是用来循环读取图片,但是运行到findcontours这里时,再往下面运行,到boundingrect这里画外接矩形出现内存越界,后来调试发现contours里面保存的数不对,contours[1]里面是0,contours[2]里面竟然是6位数,保存的xy坐标还有负数,这就很奇怪了。
很简单的程序竟然出现这种问题,后来我把程序拷到别人的电脑上,竟然完美运行,搞得我有些头大。
后来经过寻找,应该是vector矢量越界了,但是为什么把boundingrect去掉后可以运行,我就不知道为什么了。
后来发现,因为之前用的vs2012不能用了,所以又用回了vs2010,opencv的配置地址没有改,改完后没有用,后来在网上有人说,最好在用vector时事先给它分配地址,于是改成
//vector<vector<Point>>contours;
vector<Mat>contours(500);
运行成功。
我记得之前用vc6.0+opencv1的时候出现过连通域的内存泄漏,不断地往上涨,后来也没有发现为什么,也是换电脑解决的。
非常有可能时因为没有事先分配内存导致的,所以要注意。
注:万一分配的内存不够大,这样可能会导致崩溃,这样算法就存在不稳定因素。最好还是找到为什么有的电脑可以稳定运行而有的不行的原因,然后解决掉。
所以说如果有人看到这篇文章,正好还知道为什么,还请告知一下,多谢了。