Jump to content
Compvision.ru
K0rG

Распознавание номерного знака, расп. текста.

Recommended Posts

Вы молодец! Ну даже теперь и не знаю что и спросить! :) так как не можите, а мне то интересно :) эх-х-х все равно молодец!

Ну я не могу говорить про свою реализацию. А про чужую очень даже могу. Можно конечно пробовать на классификаторах, но я бы посоветовал попробовать Canny(или бинаризация) потом поиск контуров, отсеиваете те что не подходят по пропорциям и вуаля у вас номер. ну а потом сегментация и распознавание символов и эти два этапа самые сложные. https://arsocn.codeplex.com/ диплом с которого все начиналось какие то наметки там уже были

Share this post


Link to post
Share on other sites

Canny не проблема я даже вроде из стандартных примеров делал. А как искать контуры. Каким методом? Объект может быть искажен. Поворот, перспектива, наклон.

Самое интересное что потом все равно все сведется к Распознавание символов. :)

А положение рамки может тока влиять на особенность номера, ну там транзитный или обычный. 77 регион или 777

Share this post


Link to post
Share on other sites

Canny не проблема я даже вроде из стандартных примеров делал. А как искать контуры. Каким методом? Объект может быть искажен. Поворот, перспектива, наклон.

Самое интересное что потом все равно все сведется к Распознавание символов. :)

А положение рамки может тока влиять на особенность номера, ну там транзитный или обычный. 77 регион или 777

FindContours - поиск контуров

Share this post


Link to post
Share on other sites

тематическая статейка: http://robocraft.ru/blog/computervision/640.html

например задача найти цифру "1" на изображении.

получили некий контур

потом то надо счем то что то сравнить! с каким то эталоном?

или нам изначально уже надо контур "1" искать?

Share this post


Link to post
Share on other sites

Да, сравнить с эталоном.

Но контуры слишком чувствительны к шумам, для задачи поиска и распознавания номера они малопригодны.

Share this post


Link to post
Share on other sites

вопрос что брать за эталон?

и как при этом будет учитыватся маштаб, перспектива, наклон, поворот? шумы?

Share this post


Link to post
Share on other sites

Ты ищещь единицу на автомобильном номере? Тогда разумно было бы взять за эталон контур единицы на изображении автомобильного номера.

К шумам контуры, повторюсь, чувствительны.

К масштабу и повороту инвариантны.

На счёт перспективы и наклона не уверен.

Посмотри пример

Share this post


Link to post
Share on other sites

взял Вашу подборочку циферок, создал файлик формата

Вы хотите с помощью каскадного ДЕТЕКТОРА распознавать символы?

Хотя можно опредлять конечно текст на изображении, но мне кажется если словарь большой, то детектор утратит свое главное приемущество -- скорость

На мой взгляд лучше написать абстрактный поиск символов или уже готовых табличек типа автомобильных номеров и далее уже распознавть хорошим классификатором типа сверточный сетей.

Share this post


Link to post
Share on other sites

еще на матлабе

http://www.vitki.net/ru/story/raspoznavanie-registracionnyh-nomerov-s-avtomobiley-s-pomoshchyu-matlab

п.с. где то можно достать реальных видео\фото с камер которые используются стрелка и сова они вроде называются?

  • Like 1

Share this post


Link to post
Share on other sites

В качестве эксперимента решил запустить распознавание номеров на Raspberry PI, весь код у меня на C# которого на малине мягко сказать нет. Путем перебора (с++ как бы то что нужно но "религия" не позволяет, питон это вообще не серьезно)остановился на java+javacv. Написал мааленькую тестовую программку для поиска номера которая в прицепе 60-70% находит и что приятно удивило запускается вообще без изменения как на винде так и на Raspberry (референсы только другие указать). А вот время печалит на винде с i5(2.8ггц в одно ядро разумеется) 8мс и на малине аж 160мс. Наверное есть какие то способы это ускорить но увы в яве не селен так-как вообще до вчера "в глаза ее не видел".

Ну и собственно код, правда он жутко грязные так как вырван из "контекста" да и как уже сказал языка не знаю вообще


public class main{


	public static void main(String[] args) 

	{

		BufferedImage img;

		try {

			img = ImageIO.read(new File("D:\\ScropionFoto\\машины\\1\\А011СС93 86-21 28 13.jpg") );


		IplImage image= IplImage.createFrom(img);

		IplImage gray= cvCreateImage(new CvSize(image.width(),image.height()), image.depth(), 1);

		if (image.nChannels()>1)

		cvCvtColor (image, gray,CV_BGR2GRAY);

		else

			gray=image;

		SearchRectangle sar=new  SearchRectangle();

		ArrayList<CvRect> t=new ArrayList<CvRect>();

		t.add(new CvRect(0,0,image.width(),image.height()));

		StopWatch w=new StopWatch();

		w.start();

		for(int j=0;j<1000;j++)

		{

		sar.Search(gray,t, 0, 40, 10, false);


		}

		w.stop();

		for(int i=0;i<sar.CoordinatesRectangle.size();i++)

		{

			if (sar.CoordinatesRectangle.get(i).height()>0 && sar.CoordinatesRectangle.get(i).width()>image.width()*0.2 && sar.CoordinatesRectangle.get(i).width()<image.width()*0.5 && Math.abs(sar.CoordinatesRectangle.get(i).width()/sar.CoordinatesRectangle.get(i).height()-4.5)<1)

			cvDrawRect(image,new CvPoint( sar.CoordinatesRectangle.get(i).x(),sar.CoordinatesRectangle.get(i).y()) ,

					new CvPoint( sar.CoordinatesRectangle.get(i).x()+ sar.CoordinatesRectangle.get(i).width(),sar.CoordinatesRectangle.get(i).y()+ sar.CoordinatesRectangle.get(i).height())

			, cvScalar(0.0, 256.0, 0.0, 0.0) , 3, 0, 0);


		}

		for(;

		{


			cvShowImage( String.valueOf(w.getElapsedTime()/1000), image);

			if ((char)cvWaitKey(30)==27)

				break;

		}

		} catch (IOException e) {

			// TODO Auto-generated catch block

			e.printStackTrace();

		}

	}

	}


public class SearchRectangle {


	public ArrayList<CvRect> CoordinatesRectangle;

	private IplImage OriginalImage;


	public void Search(IplImage image, ArrayList<CvRect> searchArea,

			int smotch, int up, int down, Boolean addon) {

		//////////////фигня

		CoordinatesRectangle = new ArrayList<CvRect>();

		OriginalImage = image;

		for (int index = 0; index < searchArea.size(); index++) {

			CvRect r = searchArea.get(index);

			if ((OriginalImage.height() >= r.y())

					& (OriginalImage.width() >= r.x())) {

				IplImage tsubimage;

				if ((r.width() < image.width() | r.height() < image.height())) {

					cvSetImageROI(image, r);

					tsubimage = cvCreateImage(

							new CvSize(r.width(), r.height()), image.depth(),

							image.nChannels());

					cvCopy(image, tsubimage);

				} else

					tsubimage = image;

				double wkmin = Math.max(310.0 / image.width(), 0.4);

				double wkmax = Math.min(800.0 / image.width(), 1);

				IplImage subimage;

				double kw = 1;

				double kh = 1;


				if (addon) {

					CvSize sizeimage = new CvSize((int) (Math.round(tsubimage

							.width() * wkmin)), (int) (Math.round(tsubimage

							.height() * wkmin)));

					subimage = cvCreateImage(sizeimage, tsubimage.depth(),

							tsubimage.nChannels());

					cvResize(tsubimage, subimage);


					kw = tsubimage.width() / (sizeimage.width() * 1.0);

					kh = tsubimage.height() / (sizeimage.height() * 1.0);

					if (image != tsubimage)

						cvReleaseImage(tsubimage);

				} else {

					if (wkmax < 0.9) {

						CvSize sizeimage = new CvSize(

								(int) (Math.round(tsubimage.width() * wkmax)),

								(int) (Math.round(tsubimage.height() * wkmax)));

						subimage = cvCreateImage(sizeimage, tsubimage.depth(),

								tsubimage.nChannels());

						cvResize(tsubimage, subimage);

						kw = tsubimage.width() / (sizeimage.width() * 1.0);

						kh = tsubimage.height() / (sizeimage.height() * 1.0);

						if (image != tsubimage)

							cvReleaseImage(tsubimage);

						;

					} else


						subimage = tsubimage;


				}

				IplImage smooth;


				if (smotch > 0) {

					smooth = cvCreateImage(new CvSize(subimage.width(),

							subimage.height()), subimage.depth(),

							subimage.nChannels());

					cvSmooth(subimage, smooth, CV_GAUSSIAN, smotch);


				} else

					smooth = subimage;

				//////////сам поиск

				IplImage dst = cvCreateImage(

						new CvSize(smooth.width(), smooth.height()),

						smooth.depth(), smooth.nChannels());

				cvCanny(smooth, dst, up, down, 3);

				CvMemStorage storage = CvMemStorage.create();

				CvSeq contour = new CvSeq(null);

				cvFindContours(dst, storage, contour,

						Loader.sizeof(CvContour.class), CV_RETR_LIST,

						CV_CHAIN_APPROX_SIMPLE);

				 dst.release();


				while (contour != null && !contour.isNull()) {

					if (contour.elem_size() > 0)

					{


						CvBox2D box = cvMinAreaRect2(contour, null);


						if (Math.abs(box.angle()) < 30)


							CoordinatesRectangle.add(new CvRect(Math.round(box

									.center().x() - box.size().width() / 2),

									Math.round(box.center().y()

											- box.size().height() / 2), Math

											.round(box.size().width()), Math

											.round(box.size().height())));


						contour = contour.h_next();

					}

				}storage.release();


				if (smooth != subimage)

					cvReleaseImage(smooth);

				if (image != subimage)

					cvReleaseImage(subimage);

			}

		}


	}

}


[/code]

post-5717-0-45775800-1395099173_thumb.pn

Share this post


Link to post
Share on other sites

Вот мой ответ на распознавание авто номеров. Правда я только начинающий в OpenCV. Пример локализации номера по примеру фирмы Элвис.


Вот и сам пример делал по библиотекам Emgu 2.2

 

PlateRecognition.rar

post-6938-0-91380500-1413358145_thumb.pn

post-6938-0-31044400-1413358154_thumb.pn

  • Like 1

Share this post


Link to post
Share on other sites

Еще одна ссылка (только детектор номерной пластины, как я понял) с исходниками для iOS и Android:

http://habrahabr.ru/company/recognitor/blog/228195/

Share this post


Link to post
Share on other sites

Не изобретайте колесо. Вот готовое решение, законченное, так сказать. И с биндингами род разные языки в.т.ч. и питон. Использую в продакшине, 99% верно распознает Украинские номера, русские думаю так же, но там можно учить. https://github.com/openalpr/openalpr

Share this post


Link to post
Share on other sites

Не изобретайте колесо. Вот готовое решение, законченное, так сказать. И с биндингами род разные языки в.т.ч. и питон. Использую в продакшине, 99% верно распознает Украинские номера, русские думаю так же, но там можно учить. https://github.com/openalpr/openalpr

Если не трудно выложите файл найтроек для украинских номеров

Share this post


Link to post
Share on other sites

Если не трудно выложите файл найтроек для украинских номеров

Тоже из интереса посмотрел на этот проект:

1. поиск номера с помощью LBP каскадов;

2. в качестве OCR используется tesseract.

 

То есть не то что ничего особенного, а всё довольно примитивно. Я думаю, что Neuro либо лукавит, говоря о потрясающей точности, либо использует этот проект для распознавания номеров в супер тепличных условиях. Однозначно это не трасса и не уличное движение.

Share this post


Link to post
Share on other sites

Интересно, а что за фрагменты сверху-справа? Там вроде номер почти не появляется.

Share this post


Link to post
Share on other sites

Это нарезанные куски из второго изображения. Где показываются максимумы и минимумы кривой. Он идет первым то что находится вверху изображения (А так их много). Программа ищет максимумы за средней линии. Соответственно опускается до окончания минимума. И выдергивается горизонтальная линия из изображения. Дальше из этого горизонтальной линии беруться куски где значения за среднее линии и похоще на номер. Это и будет номер. Вот алгоритм.

Share this post


Link to post
Share on other sites

Вот проект нашел, делал давно, посмотрите, может что полезное найдете. Он, насколько помню, извлекал цифры номера, без распознавания.

Справлялся с довольно сложными случаями. Кстати, вы свой детектор тестировали на грязных номерах ?

LicensePlateDetector.zip

Share this post


Link to post
Share on other sites

На грязных врядли найдет. Но на плохо освещенных, частично номер в тени - проверял нормально работает

Share this post


Link to post
Share on other sites

Еще вот этот проект посмотрите, там вшита параметрическая модель номера.

objectmarker.cpp

данные к программке:

https://cloud.mail.ru/public/7ZU4/Hmt6Xa4Gp

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


  • Recently Browsing   0 members

    No registered users viewing this page.

×