This article is for OpenCV beginners, because I am not specialized in image, just to complete a pattern recognition of small jobs.
The main function is to automatically identify the figures in the image, including normal images, scratches and noisy images. respectively as follows
first, look at the recognition effect!
Then we'll start with some dry goods:
- OPENCV Installation and configuration: This can be expanded to write a blog post, I was nothing to match a opencv trouble to die, finally refer to the online studio2012 configuration method success, this skipped. See here your OPENCV still can not use, hurriedly don't look down, first put OpenCV well again come!
- OPENCV Basic picture operation:
- because the OPENCV has 2.0 and 3.0 version differences, so the function or type found on the web is two formats, the proposed new version, what impimage* type is the 2.0 version of the wording, I all use of mat. Must be unified well, not a new one will be old, will error.
- Read the picture imread, show imshow, wait for Waitkey, and so on, these should be familiar with the
- OpenCV the power is that almost all of the image operation it has ready-made functions to call, very convenient. More than Google, there will be a function has been implemented you want to complete the function.
- Two value: Whether it is the original image or have scratches or noise figure, the background is not clean, this effect on the recognition is very bad, so we should first binary, the black and white pixels to distinguish between the open some. But the right side of the picture is obviously darker than the left, so when the threshold is selected, it is difficult to use a fixed value to the two parts of the image is very ideal, so the use of forcing lattice higher adaptive binary (adaptivethreshold), Tips: Two histogram equalization before the value of the effect will be better.
- median filter: For noisy and scratched images, median filtering is a very good solution, the parameters of the median can be adjusted to eliminate the effects of noise. Disadvantage is the parameter is not good tune Ah, the tune of Want to die.
- Template Matching: The template can be from the source of the image you want to identify, but we have a template picture of the job, so this step can be omitted. OPENCV provides a very powerful matchtemplate function that calculates a similarity value for a given picture and template in accordance with the calculation method you specify, and stores the corresponding coordinates, all you need to do is make the values larger (or smaller, The image frame that is related to the function you specified to calculate the similarity is available
- window Scan: In order to improve the recognition rate, I set a window to scan the original, the Scan window movement set a little rule, that is, if the previous window does not match the number to fine-tune the window position, If you match to a number, move the left axis of the window to the right of the number that matches, and then repeat the scan.
Basic dry is so much, the rest is the constant parameter and scan the location of the window, the defect of this method is for different pictures, parameters and Scan window to change, such as to a row or three of rows of numbers, it must modify the function of the scan window, there are steps of each step, and so on, or quite an egg hurts!
Here are some of the core code
preprocessing, including adaptive binary and median filtering
voidPreprocess () {//Adaptive binary & median filterMat out;//Adaptive binaryAdaptivethreshold (source, source,255, Cv_adaptive_thresh_mean_c, Cv_thresh_binary, Adaptivebisize, Adaptivebiparam);//Median filterNamedwindow ("Binary"); Imshow ("Binary", source); Waitkey (0); Medianblur (Source, out, medianblursize); Namedwindow ("Medianblur"); Imshow ("Medianblur", out); Waitkey (0); Source = out; Srcresult = out;//used to display}
The
BOOL Match (Mat src) {int SRCW,SRCH,TEMPLATW, Templath, Curtemplatw,curtemplath,resulth, RESULTW; Mat Templat,result; SRCW = Src.cols; SrcH = src.rows; Double Currentminch=1; int currentindex=0; Double MinValue, MaxValue; Point Minloc, Maxloc,matchloc; /* * * * * * * Similarity calculation method * *0: Cv_tm_sqdiff squared Difference matching method, the best match value is0The worse the match, the greater the match value * *1: cv_tm_sqdiff_normed Normalized squared difference matching method * *2: Cv_tm_ccorr Correlation Matching Method: The method uses multiplication operation; The larger the value, the better the match. * *3: cv_tm_ccorr_normed Normalization Related matching method * *4: Cv_tm_ccoeff correlation coefficient matching method:1Represents a perfect match;-1Represents the worst match. **5: cv_tm_ccoeff_normed normalization correlation coefficient matching method */int methodtype=1; Cycle judgment8Number which number template is closest to the tested image for(int i=0;i<8; i++) {Templat = Templatvec[i]; TEMPLATW = Templat.cols; Templath = templat.rows;if(SRCW < TEMPLATW | | SrcH < TEMPLATH) {cout <<"The template cannot be larger than the original image"<< Endl;return 0; } RESULTW = Srcw-templatw +1; Resulth = Srch-templath +1; result = Cvcreateimage (Cvsize (RESULTW, Resulth),1,1); Matchtemplate (SRC, templat, result, methodtype); Minmaxloc (result, &minvalue, &maxvalue, &minloc, &maxloc,mat ()); If it is smaller than the current minimum, store the value, subscript, and coordinatesif(Minvalue<currentminch) {Currentminch= MinValue; Currentindex=i; matchloc.x=minloc.x+window_x; matchloc.y=minloc.y+window_y; CURTEMPLATW = TEMPLATW; Curtemplath = Templath; }}//cout<<"Min:"<<currentminch<<endl; The minimum value is smaller than the set threshold and the number is identifiedif(Currentminch<threshold) {numresult.push_back (Index[currentindex]); cout<<"section"<<countnumbers<<"The numbers are:"<<index[currentIndex]<<endl; /*cout<<the upper-left corner coordinates are: ("<<matchLoc.x<<","<<matchLoc.y<<")"<<endl; cout<<"Top Right Coordinate: ("<<matchLoc.x+templatW<<","<<matchLoc.y<<")"<<endl; cout<<"lower left corner coordinates: ("<<matchLoc.x<<","<<matchLoc.y+templatH<<")"<<endl;*/countnumbers++; Rectangle (Srcresult, Matchloc, Cvpoint (matchloc.x + CURTEMPLATW, matchloc.y+ curtemplath), Cvscalar (0,0,255)); /*namedwindow ("Tmpresult"); Imshow ("Tmpresult", Srcresult); Waitkey (0); * * window_x =matchloc.x+curtemplatw-1;return true; }//greater than the threshold is determined to be non-characters, scan the window to the right of a unit window_x++;return false; }
window scanning, virtual functions need to be implemented
virtual voidProcessscan(){SourceW = Source.cols;SourceH = source.rows; window_x =0; Window_y =3; Add 10 to increase fault tolerance bool last =false; while(window_x<Sourcew-scanwindoww+5){if(window_x+scanwindoww>SourceW) {window_x =SourceW-SCANWINDOWW; Last =true; } Mat tmp = Scanwindow (window_x,window_y); Match (TMP);if(last) Break; } window_x = -; SCANWINDOWH = *; window_y=SourceH-SCANWINDOWH; while(window_x<=Sourcew-scanwindoww-Ten) {Mat tmp = Scanwindow (window_x,window_y); Match (TMP); } }
Different classes are created for different images to achieve:
//Identify noisy imagesclassNoisypic: Publicpicture{ Public: Noisypic () {picture (); Threshold =0.5; Path="Test\\noisy.bmp"; Adaptivebisize = -; adaptivebiparam= +; Medianblursize =5; SCANWINDOWW = -; SCANWINDOWH = -; }voidDisplayresult () {cout<<"The image that is currently identified is a noisy point, and the recognition result is:"<<endl; for(unsigned intI=0; I<numresult.size (); i++) {cout<<numresult[i]<<" ";}cout<<endl;cout<<"====================================================="<<endl; Namedwindow ("Final"); Imshow ("Final", Srcresult); Waitkey (0); }};//with scratches on the imageclassDirtypic: Publicpicture{ Public: Dirtypic () {picture (); Threshold =0.48; Path="Test\\dirty.bmp"; Adaptivebisize = +; adaptivebiparam= at; Medianblursize =7; SCANWINDOWW = $; SCANWINDOWH = -; }Virtual voidDisplayresult () {cout<<"The image that is currently identified is a scratch and the recognition result is:"<<endl; for(unsigned intI=0; I<numresult.size (); i++) {cout<<numresult[i]<<" ";}cout<<endl;cout<<"====================================================="<<endl; Namedwindow ("Final"); Imshow ("Final", Srcresult); Waitkey (0); }};
Main function
int main() { //正常图像,构造函数不指定参数时,默认识别第一张图 //构造函数可以指定识别第几张图,下面以第三张为例 Picture pic = Picture(3); pic.startRecognize(); //识别有噪声图像 noisyPic noisyPic; noisyPic.startRecognize(); //识别有划痕图像 dirtyPic dirtyPic; dirtyPic.startRecognize(); //识别放大缩小图像 scale = scalePic(1); scale.startRecognize(); return0; }
For the convenience of children's shoes for reference, provided a download link, but to spend a little points of Oh! (LZ under the other is also to point Ah!) )
poke me, poke me .
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
OpenCV Digital Code identification