opencv车牌区域提取(VS2019 & c++)

主要实现对整张图片中.将车牌分割出来.
需要进行

  1. 转换为灰度值
  2. 阈值分割,去除部分区域
  3. 连通域分析
  4. 分割出车牌所在轮廓
#include<opencv2/opencv.hpp>
#include<iostream>
#include<opencv2/highgui/highgui_c.h>
#include<vector>
#include<cstdlib> 


using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
    Mat image;
    image = imread("D://7.jpg");   //读取原图像
    imshow("原图像", image);
    Mat gray;
    cvtColor(image, gray, COLOR_BGR2GRAY);    //转换为灰度图

    threshold(gray, gray, 151, 0, THRESH_TOZERO);           //阈值分割,去除无关的内容,低于下限置0
    threshold(gray, gray, 255, 255, THRESH_TOZERO_INV);     //高于上限置0
    Mat element = getStructuringElement(MORPH_RECT, Size(3, 3));      //形态学滤波 3*3的核
    morphologyEx(gray, gray, MORPH_CLOSE, element);                    //进行闭运算
    Mat stats, centroids;                            //连通域分析结果stats:对应各个轮廓的x,y,width,height和面积,centroids:中心点
    Mat labels = Mat::zeros(image.size(), CV_32S);   //表示当前像素是第几个轮廓
    int num_label = connectedComponentsWithStats(gray, labels, stats, centroids, 8, 4);   //连通域分析,num_label对于连通域个数

    for (int i = 0; i < num_label; i++)        //筛选车牌所在连通域,去除其他区域
    {
        int area = stats.at<int>(i, CC_STAT_AREA);      //当前连通域区域的面积
        int width = stats.at<int>(i, CC_STAT_WIDTH);    //宽度
        int height = stats.at<int>(i, CC_STAT_HEIGHT);   //高度
        //筛选出车牌所在区域的以外的区域,均不赋予彩色显示,并将其连通域区域的中心点去除
        //面积,宽度,高度的数值,根据实际车牌的尺寸,加上相机内参数等数据可获得,应保证范围适中;
        //不知各参数的,可通过原图进行估计
        if ((area < 6000) | (area > 10000) | (width < 100) | (width > 300) | (height < 20) | (height > 70))
        {
            centroids.at<Vec2d>(i, 0) = 0;       //将车牌以外区域的中心点去除,即取消连通域标记
            continue;
        }
    }
    int w = image.cols;     //原图像像素的列数
    int h = image.rows;     //原图像像素的行数

    Mat ROI = Mat::ones(image.size(), image.type());     //车牌提取结果值定义为全黑
    for (int i = 1; i < num_label; i++) {
        Vec2d pt = centroids.at<Vec2d>(i, 0);           //各轮廓的中心点
        int x = stats.at<int>(i, CC_STAT_LEFT);         //各轮廓的左上角x坐标
        int y = stats.at<int>(i, CC_STAT_TOP);          //各轮廓的左上角y坐标
        int width = stats.at<int>(i, CC_STAT_WIDTH);    //各轮廓的宽度(x,y)点开始到右下角
        int height = stats.at<int>(i, CC_STAT_HEIGHT);  //各轮廓的高度(x,y)点开始到右下角
        int area = stats.at<int>(i, CC_STAT_AREA);      //各轮廓的面积(x,y)点开始到右下角
        if (pt[0] != 0)          //车牌轮廓的中心点非0
        {
            cout << pt << endl;     //打印坐标值
            //将车牌区域像素提取到ROI(结果图像)中
            //如车牌图像倾斜,可利用椭圆拟合函数,获得图像角度再进行计算后分割
            for (int xx = x; xx < x + width; xx++)
                for (int yy = y; yy < y + height; yy++)
                    ROI.at<Vec3b>(yy, xx) = image.at<Vec3b>(yy, xx);
        }
    }
    imshow("车牌提取结果", ROI); //显示结果
    waitKey(0);
    return 0;
}

识别结果为:

 

 

 

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
OpenCV是一个开源的计算机视觉库,常用于图像处理和机器视觉应用,包括车牌识别。在C++中,基于OpenCV车牌识别通常涉及到深度学习技术,比如卷积神经网络(CNN)。该项目源码可能包含以下步骤: 1. 数据预处理[^1]: 项目首先需要收集或准备用于训练的车牌图片数据集,对图像进行灰度化、缩放、归一化等操作,以便于模型学习。 ```cpp cv::Mat img = imread("plate.jpg"); // 读取图片 cv::cvtColor(img, img, cv::COLOR_BGR2GRAY); // 转为灰度 resize(img, img, Size(224, 224)); // 缩放至模型输入尺寸 ``` 2. 模型加载与推理: 使用预训练的深度学习模型(如YOLOv3或Faster R-CNN),对车牌区域进行检测和识别。 ```cpp Net net = getPretrainedModel(); // 加载预训练模型 cv::Mat blob = dnn.blobFromImage(img, 1.0, Size(300, 300), Scalar(104, 117, 123), false, false); // 图像转blob net.setInput(blob); cv::Mat detections = net.forward(); // 推理并获取结果 ``` 3. 结果解析: 对检测到的车牌区域进行后处理,如非极大抑制(NMS),提取并识别车牌号码。 ```cpp std::vector<std::pair<cv::Rect, String>> plateCandidates = parseDetections(detections); // 解析出候选车牌 String recognizedPlate = recognizePlate(plateCandidates); // 使用OCR识别车牌 ``` 这个项目源码作为毕业设计,经过了严格的测试和调试,可以作为一个学习和实践OpenCV车牌识别的起点。然而,具体实现细节可能因作者的设计而异,需要查看源码以获取详细信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值