如何使用OpenCV和C ++检测车牌上的数字? [英] How to detect digits from license plates using OpenCV and C++?

查看:204
本文介绍了如何使用OpenCV和C ++检测车牌上的数字?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to detect digits from license plates. I want to boundrect and drop digit. My code mostly works, but not entirely. I don't know how to fix it.

这是我的代码

#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);

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

Next I get the erosion image and use that to detect digits.

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);

这是一些图像演示

Here is some image demo

推荐答案

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

Your code works, it just needs fine-tuning of your bounding box acceptance criteria. Change R_bs.width / (double)R_bs.height > 0.4 to R_bs.width / (double)R_bs.height > 0.3 and it will detect the bounding boxes of all digits.

这篇关于如何使用OpenCV和C ++检测车牌上的数字?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆