您的位置:首页 > 运维架构

[转]图片中的字符分割提取(基于opencv)

2016-07-10 11:06 477 查看
http://blog.csdn.net/anqing715/article/details/16883863

源图片



像这些图片的字符就比较好操作,每个字符都独立,不连在一起,所以轮廓检测最好了。
所以就有:
1.源图片转成单通道的灰阶图片
2.对灰度图像进行阈值操作得到二值图像

(对于一些手机拍的,背景色不是纯的话,可以用cvSmooth()平滑一下。)

二值化后的图片



3.轮廓检测(只获取最外层的)
4.遍历所有检测到的轮廓,用cvBoundingRect()得到每一个轮廓的外接矩形

找到的轮廓



5.抠它们出来,这步在上面的遍历中直接通过setROI方法进行提取。

最后的结果



下面是源码:

[cpp] view plain copy

print?





#include "stdafx.h"

#include "cv.h"

#include "highgui.h"

#include "cxcore.h"

int main(int argc, char* argv[])

{

IplImage* imgSrc = cvLoadImage("D:\\4.jpg",CV_LOAD_IMAGE_COLOR);

IplImage* img_gray = cvCreateImage(cvGetSize(imgSrc), IPL_DEPTH_8U, 1);

cvCvtColor(imgSrc, img_gray, CV_BGR2GRAY);

cvThreshold(img_gray, img_gray,100, 255,CV_THRESH_BINARY_INV);// CV_THRESH_BINARY_INV使得背景为黑色,字符为白色,这样找到的最外层才是字符的最外层

cvShowImage("ThresholdImg",img_gray);

CvSeq* contours = NULL;

CvMemStorage* storage = cvCreateMemStorage(0);

// 上面源图片有瑕疵可以用腐蚀,膨胀来祛除

int count = cvFindContours(img_gray, storage, &contours,sizeof(CvContour),CV_RETR_EXTERNAL);

printf("轮廓个数:%d",count);

int idx = 0;

char szName[56] = {0};

int tempCount=0;

for (CvSeq* c = contours; c != NULL; c = c->h_next) {

CvRect rc =cvBoundingRect(c,0);

// if ()

// {

// continue; 这里可以根据轮廓的大小进行筛选

// }

cvDrawRect(imgSrc, cvPoint(rc.x, rc.y), cvPoint(rc.x + rc.width, rc.y + rc.height), CV_RGB(255, 0, 0));

IplImage* imgNo = cvCreateImage(cvSize(rc.width, rc.height), IPL_DEPTH_8U, 3);

cvSetImageROI(imgSrc, rc);

cvCopyImage(imgSrc, imgNo);

cvResetImageROI(imgSrc);

sprintf(szName, "wnd_%d", idx++);

cvNamedWindow(szName);

cvShowImage(szName, imgNo); //如果想切割出来的图像从左到右排序,或从上到下,可以比较rc.x,rc.y;

cvReleaseImage(&imgNo);

}

cvNamedWindow("src");

cvShowImage("src", imgSrc);

cvWaitKey(0);

cvReleaseMemStorage(&storage);

cvReleaseImage(&imgSrc);

cvReleaseImage(&img_gray);

cvDestroyAllWindows();

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: