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

原理:首先对图片进行一系列的处理,步骤:去噪——sobel滤波——otsu阈值化——闭运算;然后绘制矩形,选择最接近的一个矩形;最后矩形轮廓提取。

#include<opencv2/opencv.hpp>
#include<iostream>
#include<opencv2/highgui/highgui_c.h>
#include<vector>
#include<cstdlib> 


using namespace cv;
using namespace std;
bool verify(RotatedRect rect) {
    float error = 0.4;
    const float aspect = 4.7272;
    int min = 15 * aspect * 15; // 面积下限
    int max = 125 * aspect * 125; // 面积上限

    float rmin = aspect - aspect * error; // 宽高比下限
    float rmax = aspect + aspect * error; // 宽高比上限

    int area = rect.size.width * rect.size.height; // 计算面积
    float r = rect.size.width / rect.size.height;  // 计算宽高比
    r = r < 1 ? 1 / r : r;

    return area >= min && area <= max && r >= rmin && r <= rmax;
}


int main()
{
    string in = "D://2.jpg";
    //将图像转换为单通道灰度图像
    Mat image = imread(in, IMREAD_GRAYSCALE); 
    Mat image2 = imread(in);
    Mat image3 = imread(in, IMREAD_GRAYSCALE);

    if (image.empty()) {
        return -1;
    }
    imshow("【原始图】", image);
    blur(image, image, Size(5, 5));  //均值滤波
    imshow("【去噪后】", image);


    Sobel(image, image, CV_8U, 1, 0, 3, 1, 0);
    imshow("【sobel滤波】", image);

    threshold(image, image, 0, 255, CV_THRESH_OTSU);
    imshow("【otsu阈值化】", image);

    Mat element = getStructuringElement(MORPH_RECT, Size(17, 3));
    morphologyEx(image, image, CV_MOP_CLOSE, element);  //形态学变换
    imshow("【闭运算】", image);

    vector<vector<Point>> contours;
    findContours(image, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
    map<int, RotatedRect> _map;//定义了一个用int作为关键字检索矩形的map对象

    for (int i = 0; i < contours.size(); i++) {
        drawContours(image, contours, i, Scalar(255), 1); // 绘制轮廓

        // 绘制矩形。minAreaRect()函数作用是包含点集最小面积的矩形。
        //这个矩形是可以有偏转角度的,可以与图像的边界不平行,()输入的点集,输出是矩形的四个点坐标
        RotatedRect rect = minAreaRect(contours[i]); 
        Point2f vertices[4];     //2维float类型的点
        rect.points(vertices);   //提取旋转矩形的四个角点
        for (int i = 0; i < 4; i++) {
            line(image, vertices[i], vertices[(i + 1) % 4], Scalar(255), 2); //四个角点连成线,最终形成旋转的矩形。
        }

        // 验证
        if (verify(rect)) {
            _map[i] = rect;
        }
    }
    imshow("【轮廓提取】", image);


    // 绘制通过验证的矩形
    int min_diff = 100000;
    int index = 0;
    const float square = 27.75;

    map<int, RotatedRect>::iterator iter;//迭代器(iterator)是一种检查容器内元素并遍历元素的数据类型
    iter = _map.begin();
    while (iter != _map.end()) {

        RotatedRect rect = iter->second;
        Point2f vertices[4];
        rect.points(vertices);
        for (int j = 0; j < 4; j++) {
            line(image, vertices[j], vertices[(j + 1) % 4], Scalar(255), 10);
        }

        // 选择最接近的矩形(没看明白)
        int perimeter = arcLength(contours[iter->first], true); //计算封闭的轮廓长度
        int area = contourArea(contours[iter->first]);          //计算轮廓面积
        if (area != 0) {
            int squareness = perimeter * perimeter / area;

            float diff = abs(squareness - square);
            if (diff < min_diff) {
                min_diff = diff;
                index = iter->first;
            }
        }
        iter++;
    }

    imshow("【通过验证】", image);


    // 绘制最接近的矩形
    RotatedRect rect = _map[index];
    Point2f vertices[4];
    rect.points(vertices);
    for (int i = 0; i < 4; i++) {
        cout << " asdf" << endl;
        line(image2, vertices[i], vertices[(i + 1) % 4], Scalar(0, 255, 0), 10);
    }
    imshow("【最接近的矩形】", image2);


    // 图像切割
    Mat image_crop;

    // 始终保持宽 > 高
    Size rect_size = rect.size;
    if (rect_size.width < rect_size.height) {
        swap(rect_size.width, rect_size.height);  //交换
    }
    getRectSubPix(image3, rect.size, rect.center, image_crop); //从原图像中提取一个感兴趣的矩形区域图像
    imshow("【切割后的车牌】", image_crop);

    waitKey(0);
    return 0;
}

 这里写图片描述

这里写图片描述

 

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
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车牌识别的起点。然而,具体实现细节可能因作者的设计而异,需要查看源码以获取详细信息。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值