目录 一、完整代码 1.1 返回值含义 1.2 main 1.3 bvdetector.h 1.4 bvdetector.cpp 二、图例 1. 原图scrImg 2.灰度图img_gray 3.二值图binImg 4.反二值图invImg
一、完整代码
1.1 返回值含义
0:表示正常(有角度);1:表示没有图片;2,表示有多条交叉图片;3,表示反面;4,表示正面反向;5:正面倾作严重,6:无效的长宽比(检验的纸条类型与当前设置纸条的类型不一致,7:表示没有点样;
1.2 main
# include "bvdetector.h" # include <opencv2/opencv.hpp> using namespace std;
using namespace cv; int main ( int argc, char * argv[ ] ) {
QString imagePath= "E:/workCode/Learn_CUDA/OPENCV_TRANDITION/4/strip1_loadImage.jpg" ; processStripImgOkFlag ( imagePath) ; return 0 ;
}
1.3 bvdetector.h
# pragma once
# include <opencv2/opencv.hpp>
# include <time.h>
# include <math.h>
# include <QString> int detect ( cv:: String imagePath, int isDebug) ;
bool getBvFromOpencv ( QString& imgPath, cv:: Mat & outputMat, int & resultID, double & tiltAngle, int & whiltBlockL_R) ;
bool processStripImgOkFlag ( QString& imgPath) ;
1.4 bvdetector.cpp
# include "bvdetector.h" using namespace std;
using namespace cv; # define PI acos ( - 1 ) ;
int moreAreaThreshold= 120000 ;
int backAreaThreshold= 60000 ;
int emptyAreaThreshold= 20000 ;
int hisThresholdY= 15000 ;
int hisThresholdX= 5000 ; const int URINE_WHITE_LEFT = 1 ;
const int URINE_WHITE_RIGHT = 2 ; const int URINE_NORMAL = 0 ;
const int URINE_EMPTY = 1 ;
const int URINE_MORE = 2 ;
const int URINE_BACK = 3 ;
const int URINE_FRONT_LEFT = 4 ;
const int ADJUST_PIXEL = 0 ; Mat rotateImg ( Mat src, double angle ) { Mat rot_mat ( 2 , 3 , CV_32FC1 ) ; Mat rotated_src; Point center = Point ( src. cols/ 2 , src. rows/ 2 ) ; rot_mat = getRotationMatrix2D ( center, angle, 1 ) ; warpAffine ( src, rotated_src, rot_mat, src. size ( ) ) ; return rotated_src;
} int judgeMore ( Mat binImg) { Scalar areas = sum ( binImg) ; double area= areas[ 0 ] / 255 ; if ( area>= moreAreaThreshold) { return 2 ; } else if ( area< emptyAreaThreshold) { return 1 ; } else { return 0 ; }
} double calAngle ( Mat edges) { vector< Vec4i> lines; double urineThea= 0 ; HoughLinesP ( edges, lines, 1 , CV_PI/ 720 , 10 , 300 , 50 ) ; if ( lines. size ( ) > 0 ) { double x1= lines[ 0 ] [ 0 ] ; double y1= lines[ 0 ] [ 1 ] ; double x2= lines[ 0 ] [ 2 ] ; double y2= lines[ 0 ] [ 3 ] ; if ( x2!= x1) { urineThea= - atan ( ( y2 - y1) / ( x2 - x1) ) ; urineThea= urineThea * 180 / PI; } } return urineThea;
} Mat getPatch ( int & resultID, int & whiltBlockL_R, Mat image, Mat edges) { Mat fullIamge = image. clone ( ) ; int topPoint = 0 ; int bottomPoint = 0 ; int leftPoint = 0 ; int rightPoint = 0 ; Mat histogramY ( image. rows, 1 , CV_32SC4, Scalar ( 0 ) ) ; reduce ( edges, histogramY, 1 , CV_REDUCE_SUM, CV_32SC4) ;
for ( int i = 0 ; i < image. rows; i++ ) { int tempPix= histogramY. at< int > ( i, 0 ) ; if ( topPoint == 0 && tempPix > hisThresholdY) { topPoint = i;
} else if ( tempPix > hisThresholdY ) { bottomPoint = i;
} }
Mat histogramX ( 1 , image. cols, CV_32SC4, Scalar ( 0 ) ) ; reduce ( edges. rowRange ( topPoint, bottomPoint) , histogramX, 0 , CV_REDUCE_SUM, CV_32SC4) ; for ( int j = 0 ; j < image. cols; j++ ) { int tempPix= histogramX. at< int > ( 0 , j) ; if ( leftPoint == 0 && tempPix > hisThresholdX) { leftPoint = j;
} else if ( tempPix > hisThresholdX ) { rightPoint = j;
} } return fullIamge. colRange ( leftPoint+ ADJUST_PIXEL, rightPoint- ADJUST_PIXEL) . rowRange ( topPoint+ ADJUST_PIXEL, bottomPoint- ADJUST_PIXEL) ; } bool getBvFromOpencv ( QString& imgPath, cv:: Mat & outputMat, int & resultID, double & tiltAngle, int & labelL_R) { clock_t start, end; start = clock ( ) ; bool result= true; if ( imgPath== nullptr) { result= false; cout << "imgPath is error" << endl; return result; } Mat scrImg= imread ( imgPath. toStdString ( ) . c_str ( ) , IMREAD_COLOR) ; if ( scrImg. empty ( ) ) { result= false; cout << "imgPath is error" << endl; return result; } Mat gray, blurImg, binImg, edgesImg; cvtColor ( scrImg, gray, COLOR_BGR2GRAY) ; GaussianBlur ( gray, blurImg, Size ( 3 , 3 ) , 0 ) ; threshold ( blurImg, binImg, 0 , 255 , THRESH_BINARY + THRESH_OTSU) ; Canny ( binImg, edgesImg, 50 , 150 ) ; int state= judgeMore ( binImg) ; switch ( state) { case 2 : resultID= URINE_MORE; result= false; break ; case 1 : resultID= URINE_EMPTY; result= false; break ; default : resultID= URINE_NORMAL; double angle= calAngle ( edgesImg) ; if ( angle* angle< 0.3 ) { angle= 0 ; } else { scrImg = rotateImg ( scrImg, - angle) ;
} tiltAngle= angle; if ( tiltAngle>= 50 ) { result= false; } cvtColor ( scrImg, gray, COLOR_BGR2GRAY) ; GaussianBlur ( gray, blurImg, Size ( 3 , 3 ) , 0 ) ; threshold ( blurImg, binImg, 0 , 255 , THRESH_BINARY + THRESH_OTSU) ; Canny ( binImg, edgesImg, 50 , 150 ) ; if ( result) outputMat= getPatch ( resultID, labelL_R, scrImg, edgesImg) ; if ( labelL_R== 1 ) { result= false; } } end = clock ( ) ; cout << "Searching time: " << difftime ( end, start) / CLOCKS_PER_SEC << endl; return result;
} void getPatch ( Mat image, Mat edges) { Mat fullIamge = image. clone ( ) ; int topPoint = 0 ; int bottomPoint = 0 ; int leftPoint = 0 ; int rightPoint = 0 ; Mat histogramY ( image. rows, 1 , CV_32SC4, Scalar ( 0 ) ) ; reduce ( edges, histogramY, 1 , CV_REDUCE_SUM, CV_32SC4) ; for ( int i = 0 ; i < image. rows; i++ ) { int tempPix= histogramY. at< int > ( i, 0 ) ; if ( topPoint == 0 && tempPix > hisThresholdY) { topPoint = i; } else if ( tempPix > hisThresholdY ) { bottomPoint = i; } } Mat histogramX ( 1 , image. cols, CV_32SC4, Scalar ( 0 ) ) ; reduce ( edges. rowRange ( topPoint, bottomPoint) , histogramX, 0 , CV_REDUCE_SUM, CV_32SC4) ; for ( int j = 0 ; j < image. cols; j++ ) { int tempPix= histogramX. at< int > ( 0 , j) ; if ( leftPoint == 0 && tempPix > hisThresholdX) { leftPoint = j; } else if ( tempPix > hisThresholdX ) { rightPoint = j; } } Mat gray, blurImg, binImg; cvtColor ( fullIamge. colRange ( leftPoint, rightPoint) . rowRange ( topPoint, bottomPoint) , gray, COLOR_BGR2GRAY) ; GaussianBlur ( gray, blurImg, Size ( 3 , 3 ) , 0 ) ; threshold ( blurImg, binImg, 0 , 1 , THRESH_BINARY + THRESH_OTSU) ; int leftx_base = sum ( binImg. colRange ( 0 , int ( binImg. cols/ 2 ) ) ) [ 0 ] ; int rightx_base = sum ( binImg. colRange ( int ( binImg. cols/ 2 ) , binImg. cols) ) [ 0 ] ; if ( rightx_base> leftx_base) { if ( rightPoint- leftPoint > 970 ) { int leftSpace= leftPoint+ 50 ; int tempLeftPoint= 0 ; Mat temphistogramX= histogramX. colRange ( leftSpace, image. cols) ; for ( int i = 0 ; i < temphistogramX. cols; i++ ) { int tempPix= temphistogramX. at< int > ( 0 , i) ; if ( tempLeftPoint == 0 && tempPix > hisThresholdX) { tempLeftPoint = i; break ; } } leftPoint= tempLeftPoint+ leftSpace; } } else { if ( rightPoint- leftPoint > 970 ) { int temprightPoint= rightPoint- 50 ; Mat temphistogramX= histogramX. colRange ( 0 , temprightPoint) ; for ( int i = 0 ; i < temphistogramX. cols; i++ ) { int tempPix= temphistogramX. at< int > ( 0 , i) ; if ( tempPix > hisThresholdX) { temprightPoint = i; } } rightPoint= temprightPoint; } }
} int detect ( String imagePath, int isDebug = 1 ) { clock_t start, end; start = clock ( ) ; Mat scrImg= imread ( imagePath, IMREAD_COLOR) ; Mat gray, blurImg, binImg, edgesImg; cvtColor ( scrImg, gray, COLOR_BGR2GRAY) ; GaussianBlur ( gray, blurImg, Size ( 3 , 3 ) , 0 ) ; threshold ( blurImg, binImg, 0 , 255 , THRESH_BINARY + THRESH_OTSU) ; Canny ( blurImg, edgesImg, 50 , 150 ) ; int state= judgeMore ( binImg) ; switch ( state) { case 3 : cout << "more than single strip." << endl; break ; case 2 : cout << "contain back strip." << endl; break ; case 1 : cout << "contain empty strip." << endl; break ; default : cout << "single strip." << endl; double angle= calAngle ( edgesImg) ; cout << "angle:" << angle << endl; if ( angle* angle< 0.3 ) { angle= 0 ; } else { scrImg = rotateImg ( scrImg, - angle) ; edgesImg= rotateImg ( edgesImg, - angle) ; } } end = clock ( ) ; cout << "Searching time: " << difftime ( end, start) / CLOCKS_PER_SEC << endl; waitKey ( 0 ) ; return 1 ;
} bool processStripImgOkFlag ( QString& imgPath) { clock_t start, end; start = clock ( ) ; bool result= true; int thresh_length= 45 ; if ( imgPath== nullptr) { result= false; cout << "imgPath is error" << endl; return result; } Mat scrImg= imread ( imgPath. toStdString ( ) . c_str ( ) , IMREAD_COLOR) ; if ( scrImg. empty ( ) ) { result= false; cout << "imgPath is error" << endl; return result; } vector< vector< Point>> contours; vector< Vec4i> hierarchy; Mat img_gray, binImg, invImg; cvtColor ( scrImg, img_gray, COLOR_BGR2GRAY) ; imwrite ( "d:/img_gray.jpg" , img_gray) ; threshold ( img_gray, binImg, 40 , 255 , THRESH_BINARY) ; threshold ( img_gray, invImg, 40 , 255 , THRESH_BINARY_INV) ; imwrite ( "d:/binImg.jpg" , binImg) ; imwrite ( "d:/invImg.jpg" , invImg) ; findContours ( binImg, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point ( ) ) ; int max_area= 0 , max_id= 0 ; for ( int i = 0 ; i< contours. size ( ) ; i++ ) { int temp= contourArea ( contours[ i] ) ; if ( temp> max_area) { max_area= temp; max_id= i; } } int left= scrImg. cols, right= 0 ; int offset= 20 ; for ( int i = 0 ; i< contours[ max_id] . size ( ) ; i++ ) { Point tempPoint= contours[ max_id] [ i] ; if ( tempPoint. x< left) { left= tempPoint. x; } if ( tempPoint. x> right) { right= tempPoint. x; } } left+= offset; right-= offset; Mat histogramX ( 1 , right- left+ 1 , CV_32SC4, Scalar ( 0 ) ) ; reduce ( invImg. colRange ( left, right+ 1 ) , histogramX, 0 , CV_REDUCE_SUM, CV_32SC4) ; int blank_length= 0 ; for ( int j = 0 ; j < histogramX. cols; j++ ) { int tempPix= histogramX. at< int > ( 0 , j) ;
if ( tempPix> 0 ) blank_length++ ; } if ( blank_length> thresh_length) { result= false; } cout<< result<< " blank_length:" << blank_length<< endl; end = clock ( ) ; cout << "Searching time: " << difftime ( end, start) / CLOCKS_PER_SEC << endl; return result;
}
二、图例
1. 原图scrImg
2.灰度图img_gray
3.二值图binImg
4.反二值图invImg