Перейти к содержимому
Compvision.ru
K0rG

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

Recommended Posts

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

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

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

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

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

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

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

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

В качестве эксперимента решил запустить распознавание номеров на 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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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


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

 

PlateRecognition.rar

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

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

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

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

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

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

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

LicensePlateDetector.zip

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

objectmarker.cpp

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте учётную запись или войдите для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать учётную запись

Зарегистрируйтесь для создания учётной записи. Это просто!

Зарегистрировать учётную запись

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас


  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу

×