车牌区域定位——opencv

来源:互联网 发布:淘宝如何解除卖家身份 编辑:程序博客网 时间:2024/05/08 22:43
#include<opencv2/core.hpp>#include<opencv2/highgui.hpp>#include<opencv2/imgproc.hpp>#include<iostream>using namespace std;using namespace cv;void getBlueMask(IplImage*src, IplImage*dst);int main(){//读入原始图像IplImage*src_image=cvLoadImage("C:\\Users\\aoe\\Desktop\\chepai-matlab\\chepai3.jpg");//生成原始图像的一个副本,方便处理IplImage *Psrc_image = cvCreateImage(cvGetSize(src_image), src_image->depth, src_image->nChannels);Psrc_image = cvCloneImage(src_image);//将RGB模型转换成HSV模型IplImage *hsv = cvCreateImage(cvGetSize(Psrc_image), IPL_DEPTH_8U, 3);cvCvtColor(Psrc_image, hsv, CV_BGR2HSV);//将彩色图像转换成灰度图像IplImage*blue = cvCreateImage(cvGetSize(Psrc_image), IPL_DEPTH_8U, 1);cvCvtColor(Psrc_image, blue, CV_BGR2GRAY);//利用车牌蓝底白字对车牌区域进行检索,车色车牌区域保留,非车牌区域置0getBlueMask(hsv, blue);cvNamedWindow("blue");cvShowImage("blue", blue);//二值化,将车牌区域置为白色IplImage*bin = cvCreateImage(cvGetSize(Psrc_image), IPL_DEPTH_8U, 1);cvThreshold(blue, bin, 0, 255, CV_THRESH_BINARY);cvNamedWindow("bin");cvShowImage("bin", bin);//保留一个副本IplImage*image = cvCreateImage(cvGetSize(Psrc_image), IPL_DEPTH_8U, 1);cvCopy(bin, image);cvNamedWindow("image");cvShowImage("image", image);//水平投影int level_shadow[2048];int height = Psrc_image->height;int width = Psrc_image->width;CvScalar s_shadow;//内存初始化memset(level_shadow, 0, sizeof(level_shadow));for (int j = height - 1; j >= 0; j--){    for (int i = 0; i < width; i++)    {        s_shadow = cvGet2D(image, j, i);        if (s_shadow.val[0] != 0)        {            level_shadow[j]++;//统计每行不为零的像素个数        }    }}//若每一行的像素累加和除以上一行的像素累加和小于一个阈值,则将其像素累加和置0for (int j = height - 1; j >= 1; j--){    if (level_shadow[j - 1] != 0)    {        if ((float(level_shadow[j])) / (float(level_shadow[j - 1])) < 0.6)            level_shadow[j] = 0;    }}for (int j = height - 1; j >= 0; j--){    if (level_shadow[j] != 0)        level_shadow[j] = level_shadow[j + 1] + 1;//统计水平像素不为0的区间}int y_min = 0;int y_max = 0;int m_max_value = 0;m_max_value = level_shadow[0];for (int j = 0; j < height; j++){    if (level_shadow[j]>m_max_value)    {        m_max_value = level_shadow[j];//求取车牌区域最小行和车牌区域最大行及车牌区域的高度        y_min = j;        y_max = y_min + m_max_value;    }}if (m_max_value < 10)    cout << "提取车牌高度失败!" << endl;CvRect ROI_Plate_Height;ROI_Plate_Height.x = 0;ROI_Plate_Height.y = y_min;ROI_Plate_Height.width = Psrc_image->width;ROI_Plate_Height.height = m_max_value;cvSetImageROI(image, ROI_Plate_Height);//裁剪车牌区域IplImage*pROI_Height_Image = cvCreateImage(cvSize(ROI_Plate_Height.width, ROI_Plate_Height.height),8, 1);cvCopy(image, pROI_Height_Image);int copy_m_max_value = m_max_value;while ((copy_m_max_value % 3) != 0){    copy_m_max_value--;}int Close_width = int(copy_m_max_value*0.6);int Close_height = copy_m_max_value;//闭运算IplConvKernel*pKernel_Close = cvCreateStructuringElementEx(Close_width, Close_height, Close_width / 2, Close_width / 2, CV_SHAPE_RECT, NULL);cvMorphologyEx(pROI_Height_Image, pROI_Height_Image, NULL, pKernel_Close, CV_MOP_CLOSE, 1);cvNamedWindow("pROI_Height_Image");cvShowImage("pROI_Height_Image", pROI_Height_Image);int x_min = 0;int x_max = 0;int m_row_max_value = 0;int count_row[2048];memset(count_row, 0, sizeof(count_row));//统计车牌的宽度int mid_height = m_max_value / 2;uchar*ptr_mid = (uchar*)(pROI_Height_Image->imageData + mid_height*pROI_Height_Image->widthStep);for (int i = width - 1; i >= 0; i--){    if (ptr_mid[i] != 0)        count_row[i] = count_row[i + 1] + 1;}int max_value_count_row = count_row[0];for (int i = 0; i < width; i++){    if (count_row[i]>max_value_count_row)    {        max_value_count_row = count_row[i];//求取车牌区域最小列和车牌区域最大列及车牌区域的宽度        x_min = i;        x_max = x_min + max_value_count_row;    }}if (float(max_value_count_row) / float(m_max_value)<3 || float(max_value_count_row) / float(m_max_value)>6)    cout << "提取车牌高度失败!" << endl;CvRect ROI_Plate;ROI_Plate.x = x_min;ROI_Plate.y = y_min;ROI_Plate.width = max_value_count_row;ROI_Plate.height = m_max_value;if (ROI_Plate.x<0 || ROI_Plate.x>width)    cout << "提取车牌高度失败!" << endl;if (ROI_Plate.y<0 || ROI_Plate.y>height)    cout << "提取车牌高度失败!" << endl;if ((ROI_Plate.x + ROI_Plate.width)>width)    cout << "提取车牌高度失败!" << endl;if ((ROI_Plate.y + ROI_Plate.height)>height)    cout << "提取车牌高度失败!" << endl;cvSetImageROI(bin, ROI_Plate);IplImage*plate_image = cvCreateImage(cvSize(ROI_Plate.width, ROI_Plate.height), 8, 1);cvCopy(bin, plate_image);cvNot(plate_image, plate_image);cvNamedWindow("plate_image");cvShowImage("plate_image", plate_image);cvWaitKey();}void getBlueMask(IplImage*src, IplImage*dst){    int h, s, v;    int hi = 120, lo = 100;    int lo_sat_v = 110;    for (int i = 0; i < src->height; i++)    {        uchar*ptr = (uchar*)(src->imageData + i*src->widthStep);        uchar*ptr2 = (uchar*)(dst->imageData + i*dst->widthStep);        for (int j = 0; j < src->width; j++)        {            h = ptr[3*j + 0];            s = ptr[3*j + 1];            v = ptr[3*j + 2];            if ((s < lo_sat_v || v<lo_sat_v) || (h>hi || h < lo))            {                ptr2[j] = 0;            }        }    }}
0 0
原创粉丝点击