http://blog.csdn.net/anqing715/article/details/16883863
源圖片
像這些圖片的字符就比較好操作,每個字符都獨立,不連在一起,所以輪廓檢測最好了。
所以就有:
1.源圖片轉成單通道的灰階圖片
2.對灰度圖像進行閾值操作得到二值圖像
(對於一些手機拍的,背景色不是純的話,可以用cvSmooth()平滑一下。)
二值化后的圖片
3.輪廓檢測(只獲取最外層的)
4.遍歷所有檢測到的輪廓,用cvBoundingRect()得到每一個輪廓的外接矩形
找到的輪廓
5.摳它們出來,這步在上面的遍歷中直接通過setROI方法進行提取。
最后的結果
下面是源碼:
- #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;
- }