안전은 항상 인류의 주요 관심사였습니다. 오늘날 우리는 안전함을 느낄 수 있도록 학교, 병원 및 기타 모든 공공 장소에 비디오 감시 카메라를 설치하고 있습니다. HIS의 조사에 따르면 2014 년에 약 2 억 4,500 만 대의 보안 카메라가 설치되어 작동하는 것으로 추정되며 이는 지구상의 30 명당 보안 카메라 한 대를 보유한 것과 같습니다. 특히 이미지 처리 및 기계 학습의 기술이 발전함에 따라 비디오 피드에서 정보를 처리하도록 교육함으로써 이러한 카메라를 더 스마트하게 만들 수 있습니다.
이 카메라의 비디오 피드는 얼굴 인식, 패턴 분석, 감정 분석 등을 수행하는 데 사용할 수 있으며 FF7 영화에 나오는 "신의 눈"과 같은 것에 가깝게 만들 수 있습니다. 실제로 Hikvision과 같은 감시 회사는 이미 제품에 이러한 기능을 구현하기 시작했습니다. 이전에 MATLAB 이미지 처리를 사용하여 번호판을 읽었습니다. 오늘이 기사에서는 Raspberry Pi 및 OpenCV를 사용하여 자동차에서 번호판 번호를 인식하고 읽는 방법을 배웁니다. Google에서 가져온 임의의 차량 이미지를 사용하고 OpenCV Contour Detection을 사용하여 번호판을 인식하는 프로그램을 작성한 다음 Tesseract OCR을 사용하여 번호판에서 번호를 읽습니다. 재미있을 것 같네요! 시작하겠습니다.
전제 조건
앞에서 말했듯이 OpenCV 라이브러리를 사용하여 얼굴을 감지하고 인식합니다. 따라서이 튜토리얼을 진행하기 전에 Raspberry Pi에 OpenCV 라이브러리를 설치해야합니다. 또한 2A 어댑터로 Pi에 전원을 공급하고 더 쉬운 디버깅을 위해 디스플레이 모니터에 연결합니다.
이 튜토리얼은 OpenCV가 정확히 어떻게 작동하는지 설명하지 않습니다. 이미지 처리에 관심이 있다면이 OpenCV 기본 사항과 고급 이미지 처리 튜토리얼을 확인하세요. OpenCV를 사용하는이 이미지 분할 자습서에서 윤곽선, Blob 감지 등에 대해 배울 수도 있습니다. 이미지에서 자동차의 번호판을 감지하기 위해 이와 유사한 작업을 수행합니다.
Raspberry Pi를 사용한 번호판 인식과 관련된 단계
LPR (License Plate Recognition)은 세 가지 주요 단계를 포함합니다. 단계는 다음과 같습니다
1. 번호판 감지: 첫 번째 단계는 자동차에서 번호판을 감지하는 것입니다. OpenCV의 contour 옵션을 사용하여 직사각형 개체를 감지하여 번호판을 찾습니다. 번호판의 정확한 크기, 색상 및 대략적인 위치를 알고 있으면 정확도가 향상 될 수 있습니다. 일반적으로 감지 알고리즘은 특정 국가에서 사용되는 카메라 위치 및 번호판 유형을 기반으로 학습됩니다. 이미지에 자동차가없는 경우에는 더 까다로워집니다.이 경우 자동차와 번호판을 감지하는 추가 단계를 수행합니다.
2. 문자 분할: 번호판을 감지하면 잘라내어 새 이미지로 저장해야합니다. 다시 OpenCV를 사용하여 쉽게 수행 할 수 있습니다.
3. 문자 인식: 이제 이전 단계에서 얻은 새 이미지에 일부 문자 (숫자 / 알파벳)가 기록되어 있습니다. 따라서 숫자를 감지하기 위해 OCR (Optical Character Recognition)을 수행 할 수 있습니다. 이미 Raspberry Pi를 사용한 광학 문자 인식 (OCR)에 대해 설명했습니다.
1. 번호판 감지
이 Raspberry Pi 번호판 판독기 의 첫 번째 단계는 번호판 을 감지하는 것입니다. 자동차의 샘플 이미지를 가져 와서 해당 자동차의 번호판을 감지 해 보겠습니다. 그런 다음 문자 분할 및 문자 인식에도 동일한 이미지를 사용합니다. 설명없이 바로 코드로 이동하려면 전체 코드가 제공되는이 페이지의 맨 아래로 스크롤 할 수 있습니다. 이 튜토리얼에 사용중인 테스트 이미지는 다음과 같습니다.
1 단계: 이미지를 필요한 크기로 조정 한 다음 회색조로 조정합니다. 동일한 코드는 다음과 같습니다.
img = cv2.resize (img, (620,480)) gray = cv2.cvtColor (img, cv2.COLOR_BGR2GRAY) # 그레이 스케일로 변환
크기 조정 우리는 더 큰 해상도 이미지의 문제를 피하는 데 도움이되며 크기 조정 후에도 번호판이 프레임에 남아 있는지 확인합니다. 그레이 스케일링은 모든 이미지 처리 단계에서 일반적입니다. 이렇게하면 이미지를 처리 할 때 더 이상 색상 세부 사항을 다룰 필요가없는 다른 후속 프로세스 사인 속도가 빨라집니다. 이 단계가 완료되면 이미지가 다음과 같이 변형됩니다.
2 단계: 모든 이미지에는 유용하고 쓸모없는 정보가 있습니다.이 경우에는 번호판 만이 유용한 정보이며 나머지는 프로그램에 거의 쓸모가 없습니다. 이 쓸모없는 정보를 노이즈라고합니다. 일반적으로 양방향 필터 (Bluring)를 사용하면 이미지에서 원하지 않는 세부 정보가 제거됩니다. 동일한 코드는
회색 = cv2.bilateralFilter (회색, 11, 17, 17)
구문은 destination_image = cv2.bilateralFilter (source_image, 픽셀 직경, sigmaColor, sigmaSpace)입니다. 시그마 색상과 시그마 공간을 17에서 더 높은 값으로 늘려 더 많은 배경 정보를 흐리게 처리 할 수 있지만 유용한 부분이 흐리게 처리되지 않도록주의하십시오. 출력 이미지는이 이미지에서 배경 세부 정보 (나무 및 건물)가 흐릿한 것을 볼 수 있으므로 아래와 같습니다. 이렇게하면 나중에 프로그램이 이러한 지역에 집중되는 것을 방지 할 수 있습니다.
3 단계: 가장자리 감지를 수행하는 다음 단계는 흥미 롭습니다. 이를 수행하는 방법에는 여러 가지가 있으며 가장 쉽고 인기있는 방법은 OpenCV 의 캐니 에지 방법 을 사용하는 것 입니다. 동일한 작업을 수행하는 줄은 다음과 같습니다.
edged = cv2.Canny (gray, 30, 200) #Perform Edge detection
구문은 destination_image = cv2.Canny (source_image, thresholdValue 1, thresholdValue 2)입니다. Threshold Vale 1 및 Threshold Value 2는 최소 및 최대 임계 값입니다. 최소 임계 값보다 크고 최대 임계 값보다 작은 강도 그라데이션이있는 가장자리 만 표시됩니다. 결과 이미지는 아래와 같습니다.
4 단계: 이제 이미지 에서 윤곽선을 찾을 수 있습니다. 이전 튜토리얼에서 OpenCV를 사용하여 윤곽선을 찾는 방법에 대해 이미 배웠으므로 똑같이 진행합니다.
nts = cv2.findContours (edged.copy (), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) cnts = imutils.grab_contours (cnts) cnts = sorted (cnts, key = cv2.contourArea, reverse = True) screenCnt = 없음
카운터가 감지되면 큰 것에서 작은 것으로 정렬하고 나머지는 무시하고 처음 10 개의 결과 만 고려합니다. 우리의 이미지에서 카운터는 닫힌 표면을 가진 모든 것이 될 수 있지만 모든 얻은 결과 중에서 번호판 번호도 닫힌 표면이기 때문에 거기에있을 것입니다.
획득 한 결과 중 번호판 이미지를 필터링하기 위해 모든 결과를 반복하여 네면과 닫힌 그림이있는 직사각형 모양의 윤곽이 있는지 확인합니다. 번호판은 확실히 직사각형의 4 면체이기 때문에.
# 우리의 윤곽 돌이 탄소 나노 튜브의 C에 대한: #은 윤곽 대략 맞춰서 = cv2.arcLength (C, 참) 약 = cv2.approxPolyDP (C, 0.018 * 주위염, 참) 우리의 근사화 된 윤곽은 다음 네 개의 지점이있는 경우 #을 # 우리를 len (approx) == 4: screenCnt = approx break 이면 화면을 찾았다 고 가정 할 수 있습니다 .
0.018 값은 실험 값입니다. 당신은 자신에게 가장 적합한 것을 확인하기 위해 그것을 둘러 볼 수 있습니다. 또는 기계 학습을 사용하여 자동차 이미지를 기반으로 훈련 한 다음 올바른 값을 사용하여 다음 단계로 이동하십시오. 올바른 카운터를 찾으면 screenCnt 라는 변수에 저장 한 다음 그 주위에 사각형 상자를 그려 번호판을 올바르게 감지했는지 확인합니다.
5 단계: 이제 번호판이 어디에 있는지 알았으므로 나머지 정보는 우리에게 거의 쓸모가 없습니다. 그래서 우리는 번호판이있는 곳을 제외하고 전체 사진을 마스킹 할 수 있습니다 . 동일한 작업을 수행하는 코드는 다음과 같습니다.
# 번호판 이외의 부분 마스킹 mask = np.zeros (gray.shape, np.uint8) new_image = cv2.drawContours (mask,, 0,255, -1,) new_image = cv2.bitwise_and (img, img, mask = 마스크)
마스크 된 새 이미지는 아래와 같이 나타납니다.
2. 캐릭터 분할
Raspberry Pi 번호판 인식 의 다음 단계 는 이미지를 자르고 새 이미지로 저장 하여 번호판을 이미지에서 분할하는 것입니다 . 그런 다음이 이미지를 사용하여 그 안의 캐릭터를 감지 할 수 있습니다. 메인 이미지에서 ROI (관심 지역) 이미지를 자르는 코드는 다음과 같습니다.
# 이제 자르기 (x, y) = np.where (mask == 255) (topx, topy) = (np.min (x), np.min (y)) (bottomx, bottomy) = (np.max (x), np.max (y)) 잘림 = 회색
결과 이미지는 아래와 같습니다. 일반적으로 이미지 자르기에 추가되며 필요한 경우 회색으로 처리하고 가장자리를 지정할 수도 있습니다. 이것은 다음 단계에서 문자 인식을 향상시키기 위해 수행됩니다. 그러나 원본 이미지에서도 잘 작동한다는 것을 알았습니다.
3. 문자 인식
이 Raspberry Pi 번호판 인식 의 마지막 단계 는 분할 된 이미지에서 번호판 정보 를 실제로 읽는 것 입니다. 이전 튜토리얼에서했던 것처럼 이미지에서 문자를 읽기 위해 pytesseract 패키지를 사용할 것 입니다. 동일한 코드는 다음과 같습니다.
# 번호판 텍스트 읽기 = pytesseract.image_to_string (Cropped, config = '-psm 11') print ("Detected Number is:", text)
우리는 이미 Tesseract 엔진을 구성하는 방법을 설명 했으므로 필요한 경우 여기에서 다시 Tesseract OCR을 구성하여 필요한 경우 더 나은 결과를 얻을 수 있습니다. 감지 된 문자는 콘솔에 인쇄됩니다. 컴파일하면 결과는 아래와 같습니다.
보시다시피 원본 이미지에는“HR 25 BR9044”라는 숫자가 있고 프로그램이 화면에 동일한 값을 인쇄하는 것을 감지했습니다.
번호판 인식 실패 사례
이 Raspberry Pi License Plate Recognition 의 전체 프로젝트 파일 은 여기에서 다운로드 할 수 있으며, 여기에는 프로그램을 확인하는 데 사용한 프로그램과 테스트 이미지가 포함되어 있습니다. 말하지 않고이 방법의 결과는 정확하지 않을 것임을 기억해야합니다 . 정확도는 이미지의 선명도, 방향, 빛 노출 등에 따라 달라집니다. 더 나은 결과를 얻으려면 이와 함께 기계 학습 알고리즘을 구현해보십시오.
아이디어를 얻기 위해 자동차가 카메라를 직접 향하지 않는 또 다른 예를 살펴 보겠습니다.
보시다시피 우리 프로그램은 번호판을 올바르게 감지하고자를 수있었습니다. 그러나 Tesseract 도서관은 문자를 제대로 인식하지 못했습니다. 실제 "TS 08 UE 3396"대신 OCR은 "1508 ye 3396"으로 인식했습니다. 이와 같은 문제는 더 나은 방향 이미지를 사용하거나 Tesseract 엔진 을 구성하여 수정할 수 있습니다.
또 다른 최악의 시나리오는 윤곽이 번호판을 올바르게 감지하지 못하는 경우입니다. 아래 이미지에는 배경 정보가 너무 많고 조명이 좋지 않아 프로그램이 번호로 번호판을 식별하지 못했습니다. 이 경우 우리는 다시 기계 학습을 중계하거나 그림의 품질을 향상시켜야합니다.
다른 성공적인 예
대부분의 경우 이미지 품질과 방향이 정확하고 프로그램은 번호판을 식별하고 번호를 읽을 수있었습니다. 아래의 스냅 샷은 성공적인 결과를 거의 보여줍니다. 여기에 사용 된 모든 테스트 이미지와 코드는 여기에 제공된 ZIP 파일에서 사용할 수 있습니다.
Raspberry Pi를 사용한 자동 번호판 인식 을 이해 하고 직접 멋진 것을 만드는 것을 즐겼 기를 바랍니다. OpenCV 및 Tesseract로 무엇을 할 수 있다고 생각 하십니까?, 의견 섹션에서 귀하의 생각을 알려주십시오. 이 기사에 대한 질문이 있으면 아래 댓글 섹션에 남겨 두거나 다른 기술 질문에 대한 포럼을 사용하십시오.