#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/legacy/legacy.hpp>
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include<algorithm>
#include <vector>
#include <queue>
#include "signalcontour.h"
using namespace std;
using namespace cv;
//对轮廓进行排序,使得轮廓与数字的位置时从左到右的对应关系
int cmp(Rect &iter1,Rect &iter2)
{
return iter1.x<iter2.x;
}
void segmentContour(Mat image,vector<IplImage> &imageseq)
{
Mat image1=image.clone();
vector<vector<Point>> contours;
vector<vector<Point>>::iterator iter;
vector<Rect> contourRect;
vector<Rect>::iterator iterRect;
vector<Vec4i> hierarchy;
IplImage* dst=&IplImage(image);
findContours(image1, contours, hierarchy,
CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE );
for(iter=contours.begin();iter<contours.end();iter++)
{
Rect rec=boundingRect(*iter);
contourRect.push_back(rec);
}
//对轮廓排序,使得轮廓的序列是从左到右的
sort(contourRect.begin(),contourRect.end(),cmp);
int i=0;
for(iterRect=contourRect.begin();iterRect<contourRect.end();iterRect++,i++)
{
Rect rec=*iterRect;
cvSetImageROI(dst,rec);
CvSize imagesize;
imagesize.height=rec.height;
imagesize.width=rec.width;
IplImage* img=cvCreateImage(imagesize,dst->depth,dst->nChannels);
cvCopy(dst,img);
imageseq.push_back(*img);
cvResetImageROI(dst);
}
下面是对上述函数的调用测试
#include <opencv2/legacy/legacy.hpp>
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "signalcontour.h"
int main(int ac,char *arg[])
{
Mat img=imread(arg[1]);
Mat dst;
vector<IplImage> imageseq;
vector<IplImage>::iterator iter;
cvtColor(img,dst,CV_BGR2GRAY );
threshold(dst,dst,200, 255,THRESH_BINARY_INV);
//IplImage* maa=segmentContou(dst,imageseq);
segmentContour(dst,imageseq);
char buf[]="_";
char nameBuf[100];
int i=0;
printf("%d\n",imageseq.size());
for(iter=imageseq.begin();iter<imageseq.end();iter++,i++)
{
memset(nameBuf,0,sizeof(nameBuf));
char ibuf[10];
memset(ibuf,0,sizeof(ibuf));
itoa(i,ibuf,10);
strcpy(nameBuf,buf);
strcat(nameBuf,ibuf);
cvNamedWindow(nameBuf);
cvShowImage(nameBuf,&(*iter));
}
waitKey(0);
}
需要注意的是对保存在vector<IplImage> 中的小图片进行操作时(文中是取出然后显示),直接使用迭代器是会出现错误的,猜测:迭代器虽然类似于指针,应该不止是指针这么简单,他应该有自己的一个数据结构,所以把他看做指针直接使用会出现错误,利用*操作取其数据区的内容,然后&操作取得数据区的地址才行,总结一句话,就是迭代器不同于指针,他对*操作有重载。