OpenCV 자동차 번호판 포 지 셔 닝 실현(C++)
7235 단어 OpenCV자동차 번호판 위치 추적
중국의 자동차 번호판 은 보통 7 개의 문자 와 한 점 으로 구성 되 는데 자동차 번호판 문자 의 높이 와 너 비 는 각각 90mm 와 45mm 이 고 7 개의 문자 간 의 거리 도 고정 적 인 12mm 이 며 점 분할 문자 의 지름 은 10mm 이다.
사용 한 그림 은 바 이 두 에서 마음대로 찾 은 것 입 니 다.(삭제)원본 그림 과 그 레이스 케 일 그림 을 보 여 줍 니 다.
#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/imgproc/types_c.h>
using namespace std;
using namespace cv;
int main() {
//
Mat img = imread("license.jpg");
Mat gray_img;
//
cvtColor(img, gray_img, CV_BGR2GRAY);
//
imshow(" ", img);
imshow(" ", gray_img);
waitKey(0);
return 0;
}
그 레이스 케 일 이미지 의 모든 픽 셀 은 하나의 디지털 로 계량 화 되 고 컬러 이미지 의 모든 픽 셀 은 세 개의 숫자 로 구 성 된 벡터 로 계량 화 되 며 그 레이스 케 일 이미 지 를 사용 하면 후속 처리 가 더욱 편리 합 니 다.
영상 소음 감소
모든 이미 지 는 어느 정도 의 소음 을 포함 하고 대부분 상황 에서 부 드 러 운 기술(필터 또는 소음 감소 기술 이 라 고도 함)을 억제 하거나 제거 해 야 한다.이런 기술 은 2 차원 분 산 된 볼 륨 을 바탕 으로 하 는 고 스 부 드 러 움,평균 값 부 드 러 움,통계학 적 방법 을 바탕 으로 하 는 중간 값 부 드 러 움 등 을 포함한다.여 기 는 2 차원 분 산 된 볼 륨 을 바탕 으로 하 는 고 스 평활 으로 그 레이스 케 일 이미 지 를 소음 감소 처리 하고 처리 한 이미지 효 과 는 다음 과 같다.
형태학 적 처리
고 스 가 소음 을 제거 한 후에 뒤에 자동차 번호판 의 윤곽 을 더욱 정확하게 추출 하기 위해 우 리 는 이미지 에 대해 형태학 적 처 리 를 해 야 한다.여기 서 우 리 는 그것 에 대해 연산 을 하고 처리 한 후에 다음 과 같다.
연산 을 하 는 것 은 먼저 erode 를 한 다음 에 dilate 를 하 는 과정 이 바로 연산 을 하 는 것 이다.이것 은 밝기 가 비교적 높 은 작은 구역 을 제거 하고 섬세 한 점 에서 물 체 를 분리 하 며 비교적 큰 물체 에 대해 그 면적 을 뚜렷하게 바 꾸 지 않 은 상황 에서 그 경 계 를 부 드 럽 게 하 는 등 역할 을 한다.
erode 작업 은 부식 작업 입 니 다.볼 륨 과 유사 하고 이웃 도 메 인 연산 입 니 다.그러나 가중 구 합 이 아니 라 이웃 도 메 인 에 있 는 픽 셀 점 을 그 레이스 케 일 값 에 따라 정렬 한 다음 에 이 그룹의 최소 값 을 출력 그 레이스 케 일 값 으로 선택 합 니 다.
dilate 작업 은 팽창 작업 으로 부식 작업 과 유사 하 며 팽창 은 모든 위치 이웃 지역 내의 최대 치 를 취한 다.이웃 지역 내의 최대 치 를 취 하 는 것 이 므 로 팽창 한 출력 이미지 의 전체적인 밝기 의 평균 치 는 원래 그림 보다 상승 하고 이미지 에서 밝 은 물체 의 크기 는 커진다.반면 어두 운 물체 의 사 이 즈 는 줄 어 들 고 사라 진다.
한도 값 분할
초보적인 형태학 처 리 를 완성 한 후에 우 리 는 이미지 에 대해 한도 값 분할 을 해 야 한다.우 리 는 여기 서 Otsu 한도 값 처 리 를 사 용 했 고 처리 후의 효 과 는 다음 과 같다.
이미지 에 대해 디지털 처 리 를 할 때 우 리 는 이미 지 를 몇 개의 특정한,독특한 성질 을 가 진 구역 으로 나 누 어야 한다.각 구역 은 하나의 픽 셀 의 집합 을 대표 하고 모든 집합 은 하나의 물 체 를 대표 한다.이 과정 을 완성 하 는 기술 은 보통 이미지 분할 이 라 고 하 는데 이것 은 이미지 처리 에서 이미지 분석 까지 의 관건 적 인 절차 이다.사실 이 과정 은 이해 하기 어렵 지 않다.마치 우리 인류 가 경 치 를 보 는 것 과 같다.우리 가 본 세 계 는 수많은 물체 로 구성 되 어 있다.마치 교실 은 사람,책상,책,칠판 등 으로 구성 되 어 있다.우 리 는 한도 값 처 리 를 통 해 배경 에서 우리 의 연구 대상 을 분리 할 수 있 기 를 바 라 는 것 이다.
테두리 검출
Otsu 한도 값 분할 을 거 친 후에 우 리 는 이미지 에 대해 가장자리 검 사 를 해 야 한다.우 리 는 여기 서 Canny 가장자리 검 사 를 사용 하고 처리 한 결 과 는 다음 과 같다.
그 다음 에 폐 연산 과 연산 을 한 번 더 진행 하여 흰색 물체 안의 작은 검은색 구멍 구역 을 채 우 고 경 계 를 부 드 럽 게 합 니 다.처리 후의 효 과 는 다음 과 같 습 니 다.
이때,자동차 번호판 의 윤곽 은 이미 초보 적 으로 뽑 혔 지만,단지 약간의 흰색 덩어리 가 방해 하고 있 을 뿐이다.
상기 과정의 코드:
//
bool contour(Mat image, vector<vector<Point>> &contours, vector<Vec4i> &hierarchy) {
Mat img_gau, img_open, img_seg, img_edge;
//
GaussianBlur(image, img_gau, Size(7, 7), 0, 0);
//
Mat element = getStructuringElement(MORPH_RECT, Size(23, 23));
morphologyEx(img_gau, img_open, MORPH_OPEN, element);
addWeighted(img_gau, 1, img_open, -1, 0, img_open);
//
threshold(img_open, img_seg, 0, 255, THRESH_BINARY + THRESH_OTSU);
//
Canny(img_seg, img_edge, 200, 100);
element = getStructuringElement(MORPH_RECT, Size(22, 22));
morphologyEx(img_edge, img_edge, MORPH_CLOSE, element);
morphologyEx(img_edge, img_edge, MORPH_OPEN, element);
findContours(img_edge, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point());
return true;
}
윤곽 선택지금 우 리 는 이미 윤곽 이 생 겼 다.우 리 는 자동차 번호판 이 있 는 그 윤곽 을 선별 해 야 한다.자동차 번호판 의 너비 와 높 은 비례 가 고정 되 어 있 기 때문에 이 기하학 적 특징 에 따라 우 리 는 선별 을 해 야 한다.효 과 는 그림 과 같다.
코드 는 다음 과 같 습 니 다:
//
Point2f(*choose_contour(vector<vector<Point>> contours))[2] {
int size = (int)contours.size();
int i_init = 0;
Point2f (*contours_result)[2] = new Point2f[size][2];
for (int i = 0; i < size; i++){
//
RotatedRect number_rect = minAreaRect(contours[i]);
Point2f rect_point[4];
number_rect.points(rect_point);
float width = rect_point[0].x - rect_point[1].x;
float height = rect_point[0].y - rect_point[3].y;
//
if (width < height) {
float temp = width;
width= height;
height = temp;
}
float ratio = width / height;
if (2.5 < ratio && ratio < 5.5) {
contours_result[i_init][0] = rect_point[0];
contours_result[i_init][1] = rect_point[2];
i_init++;
}
}
return contours_result;
}
//
int license_gain(Point2f (*choose_license)[2], Mat img) {
int size = (int)(_msize(choose_license) / sizeof(choose_license[0]));
//
for (int i = 0; i < size; i++) {
if ((int)choose_license[i][0].x > 1 && (int)choose_license[i][0].y > 1) {
int x = (int)choose_license[i][1].x;
int y = (int)choose_license[i][1].y;
int width = (int)(choose_license[i][0].x) - (int)(choose_license[i][1].x);
int height = (int)(choose_license[i][0].y) - (int)(choose_license[i][1].y);
Rect choose_rect(x, y, width, height);
Mat number_img = img(choose_rect);
rectangle(img, choose_license[i][0], choose_license[i][1], Scalar(0, 0, 255), 2, 1, 0);
imshow(" " + to_string(i), number_img);
}
}
imshow(" ", img);
return 0;
}
마지막 main 함수:
int main() {
//
Mat img = imread("license.jpg");
Mat gray_img;
//
cvtColor(img, gray_img, CV_BGR2GRAY);
//
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
contour(gray_img, contours, hierarchy);
//
Point2f (*choose_license)[2] = choose_contour(contours);
license_gain(choose_license, img);
delete [] choose_license;
waitKey(0);
return 0;
}
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Visual Studio 2017에서 OpenCV 템플릿 프로젝트 만들기・Windows 7 Professional 64bit ・Visual Studio 2017 Version 15.9.14 · OpenCV 3.4.1 OpenCV의 도입 방법 등은 아래를 참조하십시오. Visual Stu...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.