//根据车牌倾斜角校正车牌位置
void correctionPlatePositionForAngle(IplImage *srcImage,IplImage *destImage){
IplImage *grayImage = nil;
int thinTime = 0;
IplImage *thinImage = cvCreateImage(cvSize(srcImage->width,srcImage->height),IPL_DEPTH_8U,1);
changeToGrayImageASColor(srcImage, &grayImage,1);
if (grayImage==NULL) {
return;
}
cvThin(grayImage, thinImage, thinTime);
// 3 . hough 找直线
CvMemStorage * stroge = cvCreateMemStorage(0);
CvSeq * lines = NULL;
float *fline,fTheta;
int angle;
lines = cvHoughLines2(thinImage,stroge,CV_HOUGH_STANDARD,2,CV_PI/180,50,0,0);
if (lines->total == 0) {
isContinue = NO;
return;
}
fline = (float*)cvGetSeqElem(lines,0);
fTheta = fline[1]; // 过原点与直线垂直的直线与x轴夹角
angle = (int)(fTheta *180/ CV_PI+0.5);
if (angle >= 90 && angle <= 135)
{
angle = angle -90;
}
else if (angle >0 && angle <= 45)
{
}
else if(angle >135 && angle < 180)
{
angle = 90 - angle;
}else if (angle >45 &&angle <90)
{
angle = angle -90;
}
if (angle != 0) {
float m[6];
CvMat M = cvMat( 2, 3, CV_32F, m );
CvPoint2D32f pt = cvPoint2D32f(thinImage->width/2.0, thinImage->height/2.0);
cv2DRotationMatrix(pt, angle, 1.0, &M);
cvWarpAffine(srcImage,destImage,&M,CV_INTER_AREA |CV_WARP_FILL_OUTLIERS,cvScalarAll(255));
}else{
cvCopy(srcImage, destImage);
}
cvReleaseMemStorage(&stroge);
cvReleaseImage(&thinImage);
cvReleaseImage(&grayImage);
}
//转换灰度图像,将指定颜色像素对应值255 其他颜色变为0
void changeToGrayImageASColor (IplImage *srcImage,IplImage **destImage,int flag = 1,int color = 0){
IplImage* grayImage=cvCreateImage(cvSize(srcImage->width,srcImage->height),IPL_DEPTH_8U,1);
int r,g,b;
for( int y=0; y<srcImage->height; y++ ) {
uchar* ptr = (uchar*) (srcImage->imageData + y * srcImage->widthStep);
uchar * grayPtr = (uchar *)grayImage->imageData + grayImage->widthStep * y;
for( int x=0; x<srcImage->width; x++ ) {
b = ptr[4*x] ;
g = ptr[4*x+1];
r = ptr[4*x+2];
if (flag == 1) {//blue
}
switch (flag) {
case 0://white
if (abs(r-b) < 35 && abs(g-b) < 35 && abs(r-g) < 35 &&(r > 175 || g > 175||b > 175)) {
grayPtr[x] = color?255:0;
}else{
grayPtr[x] = color?0:255;
}
;
break;
case 1://blue
if (2*b - r -g > 100) {
grayPtr[x] = color?0:255;
}else{
grayPtr[x] = color?255:0;
}
;
break;
case 2://yellow
;
break;
case 3://black
;
break;
default:
break;
}
}
}
if (destImage) {
*destImage = grayImage;
}
}
//大津法求阈值
int otsu(const IplImage *src_image)
{
double sum = 0.0;
double w0 = 0.0;
double w1 = 0.0;
double u0_temp = 0.0;
double u1_temp = 0.0;
double u0 = 0.0;
double u1 = 0.0;
double delta_temp = 0.0;
double delta_max = 0.0;
//src_image灰度级
int pixel_count[256]={0};
float pixel_pro[256]={0};
int threshold = 0;
uchar* data = (uchar*)src_image->imageData;
//统计每个灰度级中像素的个数
for(int i = 0; i < src_image->height; i++)
{
for(int j = 0;j < src_image->width;j++)
{
pixel_count[(int)data[i * src_image->width + j]]++;
sum += (int)data[i * src_image->width + j];
}
}
//计算每个灰度级的像素数目占整幅图像的比例
for(int i = 0; i < 256; i++)
{
pixel_pro[i] = (float)pixel_count[i] / ( src_image->height * src_image->width );
}
//遍历灰度级[0,255],寻找合适的threshold
for(int i = 0; i < 256; i++)
{
w0 = w1 = u0_temp = u1_temp = u0 = u1 = delta_temp = 0;
for(int j = 0; j < 256; j++)
{
if(j <= i) //背景部分
{
w0 += pixel_pro[j];
u0_temp += j * pixel_pro[j];
}
else //前景部分
{
w1 += pixel_pro[j];
u1_temp += j * pixel_pro[j];
}
}
u0 = u0_temp / w0;
u1 = u1_temp / w1;
delta_temp = (float)(w0 *w1* pow((u0 - u1), 2)) ;
if(delta_temp > delta_max)
{
delta_max = delta_temp;
threshold = i;
}
}
return threshold;
}
//图片细化处理
void cvThin( IplImage* src, IplImage* dst, int iterations)
{
//此时的src是一个二值化的图片
CvSize size = cvGetSize(src);
cvCopy(src, dst);
int n = 0,i = 0,j = 0;
for(n=0; n<iterations; n++)//开始进行迭代
{
IplImage* t_image = cvCloneImage(dst);
for(i=0; i<size.height; i++)
{
for(j=0; j<size.width; j++)
{
if(CV_IMAGE_ELEM(t_image,uchar,i,j)==255)
{
int ap=0;
int p2 = (i==0)?0:CV_IMAGE_ELEM(t_image,uchar, i-1, j);
int p3 = (i==0 || j==size.width-1)?0:CV_IMAGE_ELEM(t_image,uchar, i-1, j+1);
if (p2==0 && p3==255)
{
ap++;
}
int p4 = (j==size.width-1)?0:CV_IMAGE_ELEM(t_image,uchar,i,j+1);
if(p3==0 && p4==255)
{
ap++;
}
int p5 = (i==size.height-1 || j==size.width-1)?0:CV_IMAGE_ELEM(t_image,uchar,i+1,j+1);
if(p4==0 && p5==255)
{
ap++;
}
int p6 = (i==size.height-1)?0:CV_IMAGE_ELEM(t_image,uchar,i+1,j);
if(p5==0 && p6==1)
{
ap++;
}
int p7 = (i==size.height-1 || j==0)?0:CV_IMAGE_ELEM(t_image,uchar,i+1,j-1);
if(p6==0 && p7==255)
{
ap++;
}
int p8 = (j==0)?0:CV_IMAGE_ELEM(t_image,uchar,i,j-1);
if(p7==0 && p8==255)
{
ap++;
}
int p9 = (i==0 || j==0)?0:CV_IMAGE_ELEM(t_image,uchar,i-1,j-1);
if(p8==0 && p9==255)
{
ap++;
}
if(p9==0 && p2==255)
{
ap++;
}
if((p2+p3+p4+p5+p6+p7+p8+p9)>255 && (p2+p3+p4+p5+p6+p7+p8+p9)<7*255)
{
if(ap==1)
{
if(!(p2 && p4 && p6))
{
if(!(p4 && p6 && p8))
{
CV_IMAGE_ELEM(dst,uchar,i,j)=0;//设置目标图像中像素值为0的点
}
}
}
}
}
}
}
cvReleaseImage(&t_image);
t_image = cvCloneImage(dst);
for(i=0; i<size.height; i++)
{
for(int j=0; j<size.width; j++)
{
if(CV_IMAGE_ELEM(t_image,uchar,i,j)==255)
{
int ap=0;
int p2 = (i==0)?0:CV_IMAGE_ELEM(t_image,uchar, i-1, j);
int p3 = (i==0 || j==size.width-1)?0:CV_IMAGE_ELEM(t_image,uchar, i-1, j+1);
if (p2==0 && p3==255)
{
ap++;
}
int p4 = (j==size.width-1)?0:CV_IMAGE_ELEM(t_image,uchar,i,j+1);
if(p3==0 && p4==255)
{
ap++;
}
int p5 = (i==size.height-1 || j==size.width-1)?0:CV_IMAGE_ELEM(t_image,uchar,i+1,j+1);
if(p4==0 && p5==255)
{
ap++;
}
int p6 = (i==size.height-1)?0:CV_IMAGE_ELEM(t_image,uchar,i+1,j);
if(p5==0 && p6==255)
{
ap++;
}
int p7 = (i==size.height-1 || j==0)?0:CV_IMAGE_ELEM(t_image,uchar,i+1,j-1);
if(p6==0 && p7==255)
{
ap++;
}
int p8 = (j==0)?0:CV_IMAGE_ELEM(t_image,uchar,i,j-1);
if(p7==0 && p8==255)
{
ap++;
}
int p9 = (i==0 || j==0)?0:CV_IMAGE_ELEM(t_image,uchar,i-1,j-1);
if(p8==0 && p9==255)
{
ap++;
}
if(p9==0 && p2==255)
{
ap++;
}
if((p2+p3+p4+p5+p6+p7+p8+p9)>255 && (p2+p3+p4+p5+p6+p7+p8+p9)<7*255)
{
if(ap==1)
{
if(p2*p4*p8==0)
{
if(p2*p6*p8==0)
{
CV_IMAGE_ELEM(dst, uchar,i,j)=0;
}
}
}
}
}
}
}
cvReleaseImage(&t_image);
}
}
//计算像素点值
void countPixelsCountForEachCol(IplImage *srcImage,cv::vector<double> & pixls){
if (!srcImage) {
return;
}
for (int col = 0; col < srcImage->width; col++) {
pixls.push_back(0);
for (int row = 0; row < srcImage->height; row++) {
uchar * ptr = (uchar *)srcImage->imageData + srcImage->widthStep * row;
int data = ptr[col];
if (data > 0) {
pixls[col]++;
}
}
}
}