学习OpenCV——车牌检测(定位)

本文介绍了作者在进行车牌识别实验中尝试的几种方法,包括基于HSV和YCrCb颜色分布、Canny+Hough变换、轮廓检测、Squares方式以及结合Sobel算子与形态学操作的方法。其中,Sobel+形态学处理结合轮廓检测的方案取得了65%的正确率,但因未应用仿射变换导致效果受限。
摘要由CSDN通过智能技术生成

这两天在做关于车牌识别的实验,用了几种方式:

1.车牌颜色分布(HSV空间,YCrCb空间的没有颜色分布图谱,无法实验);利用HSV的H通道,效果一般,受环境影响大。

#include "highgui.h"
#include "cv.h"
#include <stdio.h>   
#include <math.h>  
#include <string>
#include<iostream>
using namespace std;

CvPoint Point;
IplImage* img=0;
// skin region location using rgb limitation
void SkinRGB(IplImage* rgb,IplImage* _dst)
{
	assert(rgb->nChannels==3&& _dst->nChannels==3);

	static const int R=2;
	static const int G=1;
	static const int B=0;

	IplImage* dst=cvCreateImage(cvGetSize(_dst),8,3);
	cvZero(dst);

	for (int h=0;h<rgb->height;h++) {
		unsigned char* prgb=(unsigned char*)rgb->imageData+h*rgb->widthStep;
		unsigned char* pdst=(unsigned char*)dst->imageData+h*dst->widthStep;
		for (int w=0;w<rgb->width;w++) {
			if ((prgb[R]>95 && prgb[G]>40 && prgb[B]>20 &&
				prgb[R]-prgb[B]>15 && prgb[R]-prgb[G]>15/*&&
				!(prgb[R]>170&&prgb[G]>170&&prgb[B]>170)*/)||//uniform illumination 
				(prgb[R]>200 && prgb[G]>210 && prgb[B]>170 &&
				abs(prgb[R]-prgb[B])<=15 && prgb[R]>prgb[B]&& prgb[G]>prgb[B])//lateral illumination
				) {
					memcpy(pdst,prgb,3);
			}			
			prgb+=3;
			pdst+=3;
		}
	}
	cvCopyImage(dst,_dst);
	cvReleaseImage(&dst);
}
// skin detection in rg space
void cvSkinRG(IplImage* rgb,IplImage* gray)
{
	assert(rgb->nChannels==3&&gray->nChannels==1);
	
	const int R=2;
	const int G=1;
	const int B=0;

	double Aup=-1.8423;
	double Bup=1.5294;
	double Cup=0.0422;
	double Adown=-0.7279;
	double Bdown=0.6066;
	double Cdown=0.1766;
	for (int h=0;h<rgb->height;h++) {
		unsigned char* pGray=(unsigned char*)gray->imageData+h*gray->widthStep;
		unsigned char* pRGB=(unsigned char* )rgb->imageData+h*rgb->widthStep;
		for (int w=0;w<rgb->width;w++) 
		{
			int s=pRGB[R]+pRGB[G]+pRGB[B];
			double r=(double)pRGB[R]/s;
			double g=(double)pRGB[G]/s;
			double Gup=Aup*r*r+Bup*r+Cup;
			double Gdown=Adown*r*r+Bdown*r+Cdown;
			double Wr=(r-0.33)*(r-0.33)+(g-0.33)*(g-0.33);
			if (g<Gup && g>Gdown && Wr>0.004)
			{
				*pGray=255;
			}
			else
			{ 
				*pGray=0;
			}
			pGray++;
			pRGB+=3;
		}
	}

}
// implementation of otsu algorithm
// author: onezeros#yahoo.cn
// reference: Rafael C. Gonzalez. Digital Image Processing Using MATLAB
void cvThresholdOtsu(IplImage* src, IplImage* dst)
{
	int height=src->height;
	int width=src->width;

	//histogram
	float histogram[256]={0};
	for(int i=0;i<height;i++) {
		unsigned char* p=(unsigned char*)src->imageData+src->widthStep*i;
		for(int j=0;j<width;j++) {
			histogram[*p++]++;
		}
	}
	//normalize histogram
	int size=height*width;
	for(int i=0;i<256;i++) {
		histogram[i]=histogram[i]/size;
	}

	//average pixel value
	float avgValue=0;
	for(int i=0;i<256;i++) {
		avgValue+=i*histogram[i];
	}

	int threshold;	
	float maxVariance=0;
	float w=0,u=0;
	for(int i=0;i<256;i++) {
		w+=histogram[i];
		u+=i*histogram[i];

		float t=avgValue*w-u;
		float variance=t*t/(w*(1-w));
		if(variance>maxVariance) {
			maxVariance=variance;
			threshold=i;
		}
	}

	cvThreshold(src,dst,threshold,255,CV_THRESH_BINARY);
}

void cvSkinOtsu(IplImage* src, IplImage* dst)
{
	assert(dst->nChannels==1&& src->nChannels==3);

	IplImage* ycrcb=cvCreateImage(cvGetSize(src),8,3);
	IplImage* cr=cvCreateImage(cvGetSize(src),8,1);
	cvCvtColor(src,ycrcb,CV_BGR2YCrCb);
	cvSplit(ycrcb,0,cr,0,0);

	cvThresholdOtsu(cr,cr);
	cvCopyImage(cr,dst);
	cvReleaseImage(&cr);
	cvReleaseImage(&ycrcb);
}

void cvSkinYUV(IplImage* src,IplImage* dst)
{
	IplImage* ycrcb=cvCreateImage(cvGetSize(src),8,3);
	//IplImage* cr=cvCreateImage(cvGetSize(src),8,1);
	//IplImage* cb=cvCreateImage(cvGetSize(src),8,1);
	cvCvtColor(src,ycrcb,CV_BGR2YCrCb);
	//cvSplit(ycrcb,0,cr,cb,0);

	static const int Cb=2;
	static const int Cr=1;
	static const int Y=0;

	//IplImage* dst=cvCreateImage(cvGetSize(_dst),8,3);
	cvZero(dst);

	for (int h=0;h<src->height;h++) {
		unsigned char* pycrcb=(unsigned char*)ycrcb->imageData+h*ycrcb->widthStep;
		unsigned char* psrc=(unsigned char*)src->imageData+h*src->widthStep;
		unsigned char* pdst=(unsigned char*)dst->imageData+h*dst->widthStep;
		for (int w=0;w<src->width;w++) {
			if ((pycrcb[Cr]<=126||pycrcb[Cr]>=130)&&(pycrcb[Cb]<=126||pycrcb[Cb]>=130))
			{
					memcpy(pdst,psrc,3);
			}
			pycrcb+=3;
			psrc+=3;
			pdst+=3;
		}
	}
	//cvCopyImage(dst,_dst);
	//cvReleaseImage(&dst);
}

void cvSkinHSV(IplImage* src,IplImage* dst)
{
	IplImage* hsv=cvCreateImage(cvGetSize(src),8,3);
	//IplImage* cr=cvCreateImage(cvGetSize(src),8,1);
	//IplImage* cb=cvCreateImage(cvGetSize(src),8,1);
	cvCvtColor(src,hsv,CV_BGR2HSV);
	//cvSplit(ycrcb,0,cr,cb,0);

	static const int V=2;
	static const int S=1;
	static const int H=0;

	//IplImage* dst=cvCreateImage(cvGetSize(_dst),8,3);
	cvZero(dst);

	for (int h=0;h<src->height;h++) {
		unsigned char* phsv=(unsigned char*)hsv->imageData+h*hsv->widthStep;
		unsigned char* psrc=(unsigned char*)src->imageData+h*src->widthStep;
		unsigned char* pdst
评论 53
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值