OpenCV другой подход к обнаружению го
я работаю над приложением для Android, которое распознаетGO доска и создатьФайл SGF этого
я сделал версию, которая способна обнаружить доску и деформировать перспективу, чтобы сделать ее квадратной (код и пример изображения ниже), к сожалению, становится сложнее при добавлении камней (изображение ниже)
Важные вещи о средней доске для го:
круглые черные и белые камничерные линии на доскецвет доски варьируется от белого до светло-коричневого, а иногда и с древесными зернамикамни расположены на пересечениях двух линийПоправьте меня, если я ошибаюсь, но я думаю, что мой нынешний подход не является хорошим. У кого-нибудь есть общее представление о том, как я могу отделить камни и линии от остальной части картины?
Мой код:
Mat input = inputFrame.rgba(); //original image
Mat gray = new Mat(); //grayscale image
//convert image to grayscale
Imgproc.cvtColor( input, gray, Imgproc.COLOR_RGB2GRAY);
//try to improve histogram (more contrast)
equalizeHist(gray, gray);
//blur image
Size s = new Size(5,5);
GaussianBlur(gray, gray, s, 0);
//apply adaptive treshold
adaptiveThreshold( gray, gray, 255, Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C, Imgproc.THRESH_BINARY,11,2);
//adding secondary treshold, removes a lot of noise
threshold(gray, gray, 0, 255, Imgproc.THRESH_BINARY + Imgproc.THRESH_OTSU);
Некоторые изображения:
пустая доска http://roelept82.eightytwo.axc.nl/pic/device-2016-02-15-130011.png заполненная доска http://roelept82.eightytwo.axc.nl/pic/device-2016-02-15-131431.png
РЕДАКТИРОВАТЬ: 05-03-2016
Ура! удалось правильно определить линии камней и цвета. предварительным условием изображения должна быть только сама доска, без какого-либо другого видимого фона.
Я использую houghLinesP (60 линий) и houghCircles (17 кругов), продолжительность на моем телефоне (1-го поколения Moto G) около 5 секунд.
Обнаружение платы и деформации оказывается довольно сложной задачей, когда она должна работать под разными углами и в условиях молнии ... все еще работаю над этим
Предложения по различным подходам по-прежнему приветствуются!
заполненная доска http://roelept82.eightytwo.axc.nl/pic/detect.png
РЕДАКТИРОВАТЬ: 15-03-2016
я нашел хороший способ получить линии, пересекающиеся с морфологическими преобразованиями перекрестного типа, потрясающе работает, когда изображение делается прямо над доской, к сожалению, не под углом (см. ниже)morph http://roelept82.eightytwo.axc.nl/pic/morph.png
В моем последнем обновлении я показал обнаружение линий и камней с помощью снимка, сделанного непосредственно сверху, с тех пор я работал над обнаружением доски и деформированием ее таким образом, чтобы обнаружение моей линии и камней стало полезным.
обнаружение харриса
Я изо всех сил пытался получить правильные настройки параметров, и я все еще не уверен, являются ли они оптимальными, не могу найти много информации о том, как оптимизировать изображение перед использованием углов Харриса. Прямо сейчас он обнаруживает во многих углах быть полезным. хотя кажется, что это может сработать. (верхняя строка с картинками в примере)
Mat corners = new Mat();
Imgproc.cornerHarris(image, corners, 5, 3, 0.03);
Mat mask = new Mat(corners.size(), CvType.CV_8U, new Scalar(1));
Core.MinMaxLocResult maxVal = Core.minMaxLoc(corners);
Core.inRange(corners, new Scalar(maxVal.maxVal * 0.01), new Scalar(maxVal.maxVal), mask);
морфологические преобразования кросс-типа
отлично работает, когда снимок сделан непосредственно сверху, используется под углом или с повернутой доской, не работает (средняя линия с рисунками в примере)
Imgproc.GaussianBlur(image, image, new Size(5, 5), 0);
Imgproc.adaptiveThreshold(image, image, 255, Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C, Imgproc.THRESH_BINARY_INV, 11, 2);
int morph_elem = 1; //0: Rect - 1: Cross - 2: Ellipse
int morph_size = 5;
int morph_operator = 0; //0: Opening - 1: Closing \n 2: Gradient - 3: Top Hat \n 4: Black Hat
Mat element = getStructuringElement( morph_elem, new Size(2 * morph_size + 1, 2 * morph_size + 1), new Point( morph_size, morph_size ));
morphologyEx(image, image, morph_operator + 2, element);
контур и линии
если на внешней стороне доски нет камней, а условия освещения не слишком резкие, это работает довольно хорошо. довольно часто контуры являются лишь частью доски (нижняя строка с рисунками в примере)
Imgproc.GaussianBlur(image, image, new Size(5, 5), 0);
Imgproc.adaptiveThreshold(image, image, 255, Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C, Imgproc.THRESH_BINARY_INV, 11, 2);
Mat hierarchy = new Mat();
MatOfPoint biggest = null;
int contourId = 0;
double biggestArea = 0;
double minSize = 2000;
List<MatOfPoint> contours = new ArrayList<>();
findContours(InvertedImage, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
//find biggest
for( int x = 0; x < contours.size() ; x++ ){
double area = Imgproc.contourArea(contours.get(x));
if( area > minSize && area > biggestArea ){
biggestArea = area;
biggest = contours.get(x);
contourId = x;
}
}
Обеспечивая правильную картину, все три метода работают, но недостаточно хороши, чтобы быть надежными. любые мысли о параметрах, предварительной обработке изображений, различных подходах или что-либо, что может улучшить обнаружение, приветствуются =)
сравнение http://roelept82.eightytwo.axc.nl/pic/comparison.png
РЕДАКТИРОВАТЬ: 31-03-2016
обнаружение линий и камней в значительной степени решено, поэтому я закрою этот вопрос.создал новый для точного обнаружения и деформации.
Кто-нибудь заинтересован в моем прогрессе:это мой канал GOSU Snap Alpha не ожидайте многого из этого прямо сейчас!
РЕДАКТИРОВАТЬ: 16-10-2016
Обновление: я видел, что некоторые люди все еще следуют за этим вопросом. Я протестировал еще кое-что и начал использовать Tensorflow, моя нейронная сеть выглядит многообещающе,Вы можете посмотреть на это здесь. Еще предстоит проделать большую работу, мой текущий набор данных изображений ужасен, и сейчас я работаю над получением большого набора данных.
Приложение работает лучше всего, используя квадратную доску с толстыми линиями и приличным освещением.