繁体   English   中英

如何使用 OpenCV 和 C++ 从车牌中检测数字?

[英]How to detect digits from license plates using OpenCV and C++?

我正在尝试从车牌中检测数字。 我想绑定并删除数字。 我的代码大部分都有效,但不完全有效。 我不知道如何修复它。

这是我的代码

#include <opencv\cv.h>
#include <opencv\highgui.h>
#include <opencv\ml.h>
#include <opencv\cxcore.h>
#include <opencv2\opencv.hpp>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include <opencv2\imgcodecs.hpp>
#include <stdio.h>
#include <stdlib.h>
#include<iostream>
using namespace cv;
using namespace std;
//image processing
plate = cv::imread("plate.jpg");//original image
medianBlur(plate, src, 7);//smooth
cv::cvtColor(plate, plate_gray, CV_BGR2GRAY);
cv::Mat plate_binary;
threshold(plate_gray, plate_binary, 120, 255,THRESH_BINARY);
medianBlur(plate_binary, plate_binary, 5);
cv::Mat plate_ero;// erosion
int erosion_size = 1;
int dialate_size = 0;
Mat element_ero = getStructuringElement(cv::MORPH_RECT,
    cv::Size(2 * erosion_size + 1, 2 * erosion_size + 1),
    cv::Point(erosion_size, erosion_size));
Mat element_dia = getStructuringElement(cv::MORPH_RECT,
    cv::Size(2 * dialate_size + 1, 2 * dialate_size + 1),
    cv::Point(dialate_size, dialate_size));
erode(plate_binary, plate_ero, element_ero);
dilate(plate_binary, plate_dia, element_dia);
medianBlur(plate_binary, plate_binary, 1);
cv::imshow("plate", plate);
cv::Mat plate_dia;// dalate
cv::imwrite("plate_ero.jpg", plate_ero);

接下来我得到侵蚀图像并使用它来检测数字。

cv::Mat bs;
bs = cv::imread("plate_ero.jpg");
cv::Mat bs_int;
cv::Mat bs_cany;
threshold(bs, bs_int, 150, 255, THRESH_BINARY_INV);
cv::Canny(bs_int, bs_cany, 100, 200, 3);
vector<vector<Point>> contours_bs;
vector<Vec4i> hierarchy_bs;
findContours(bs_cany, contours_bs, hierarchy_bs, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
// rectangle
vector<int> selected_bs;
Mat drawing_bs = Mat::zeros(bs_cany.size(), CV_8UC3);
Rect R_bs;
int w_threshold_bs = 10;
int h_threshold_bs = 50;
for (int i = 0; i < contours_bs.size(); i++)
{
    Scalar color_bs = Scalar(0, 255, 0);
    R_bs = boundingRect(contours[i]);
    if (R_bs.width / (double)R_bs.height > 0.4 && R_bs.width / (double)R_bs.height < 0.6 && R_bs.width > 10 && R_bs.height > 40 && R_bs.width < 100 && R_bs.height < 200)
    {
        selected_bs.push_back(i);
        drawContours(drawing_bs, contours_bs, i, color_bs, 2, 8, hierarchy_bs, 0, Point());
    }
}

for (size_t i = 0; i < selected_bs.size(); i++)
{
    rectangle(plate, boundingRect(contours_bs[selected_bs[i]]), Scalar(0, 0, 255), 5);
}
cv::imwrite("so.jpg", plate);
cv::waitKey(0);
return(0);

这是一些图像演示Plate_original

Plate_ero

版材输出

您的代码有效,它只需要微调您的边界框接受标准。 R_bs.width / (double)R_bs.height > 0.4更改为R_bs.width / (double)R_bs.height > 0.3 ,它将检测所有数字的边界框。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM