Я создаю приложение для родителя моего друга, который, к сожалению, имел удар, и больше не может говорить, читать или заклинание. Однако он может сделать довольно подробные чертежи.
В настоящее время я создал приложение, которое может обрабатывать изображение чертежа и обнаруживать основные фигуры. (Линии, квадраты и треугольники) Приложение может подсчитать, сколько из каждой фигуры было нарисовано, поэтому он знает разницу между изображением с двумя квадратами, приложенными к изображению с одним квадратом.
Это накладывает на пользователя большую часть когнитивной нагрузки, чтобы запомнить все комбинации фигур и то, что они означают. В настоящее время я обнаруживаю контуры изображения через
То, что я хотел бы достичь, - это то, что пользователь рисует фигуру, добавляет ее в банк известных чертежей, а затем каждый раз, когда он рисует изображение, приложение обрабатывает каждое известное изображение, сравнивая его с исходным изображением и сохраняя значение подобия, Затем, принимая наивысшее значение подобия, при условии, что оно выше порогового значения, его можно принять за изображение, изображенное на рисунке.
Я изучил соответствие OpenCV Pattern Matching, а также Templating, но с ненадежными результатами.
Я прошу совета относительно наилучшего подхода, который обеспечит результат, на который я надеюсь.
Я построил рекламное видео для моей университетской лекции, чтобы лучше показать, что делает приложение. Если вас это интересует, вы можете посмотреть его здесь. https://youtu.be/ngMUUIsLHoc
Спасибо заранее.
Ответ 4
Один метод, который может помочь, из-за того, как долго эта библиотека была вокруг и насколько хорошо она поддерживается, является использование ImageMagick. Позвольте мне продемонстрировать.
1 установите Pod, используя
pod 'ImageMagick', '6.8.8-9'
2 в viewController или любом другом представлении, которое вы хотите сравнить с изображениями, импортируйте следующее:
#import <wand/MagickWand.h>
4 создайте исключение в режиме легкого режима "Макро" для проверки ошибок без необходимости кодирования метода исключения каждый раз, когда вам нужно проверить исключения:
#define ThrowWandException(wand) { \
char * description; \
ExceptionType severity; \
\
description = MagickGetException(wand,&severity); \
(void) fprintf(stderr, "%s %s %lu %s\n", GetMagickModule(), description); \
description = (char *) MagickRelinquishMemory(description); \
exit(-1); \
}
3 создайте метод сравнения для сравнения двух изображений:
-(void)compareTwoImages:(UIImage*)firstImage secondImage:(UIImage*)secondImage comparitorSize:(size_t)comparitorSize {
double diff1, diff2, diff3, diff4, diff5, diff6, diff7, diff8, diff9, diff10, diff11, diff12;
MagickWandGenesis();
MagickWand *magick_wand_1 = NewMagickWand();
NSData * dataObject1 = UIImagePNGRepresentation(firstImage);
MagickBooleanType status1;
status1 = MagickReadImageBlob(magick_wand_1, [dataObject1 bytes], [dataObject1 length]);
if (status1 == MagickFalse) {
ThrowWandException(magick_wand_1);
}
MagickWandGenesis();
MagickWand *magick_wand_2 = NewMagickWand();
NSData * dataObject11 = UIImagePNGRepresentation(secondImage);
MagickBooleanType status11;
status11 = MagickReadImageBlob(magick_wand_2, [dataObject11 bytes], [dataObject11 length]);
if (status11 == MagickFalse) {
ThrowWandException(magick_wand_2);
}
MagickScaleImage(magick_wand_2, comparitorSize, comparitorSize);
MagickScaleImage(magick_wand_1, comparitorSize, comparitorSize);
MagickWandGenesis();
MagickWand *magick_wand_3 = NewMagickWand();
MagickCompareImages(magick_wand_1, magick_wand_2, UndefinedMetric, &diff1);
MagickCompareImages(magick_wand_1, magick_wand_2, AbsoluteErrorMetric, &diff2);
MagickCompareImages(magick_wand_1, magick_wand_2, MeanAbsoluteErrorMetric, &diff3);
MagickCompareImages(magick_wand_1, magick_wand_2, MeanErrorPerPixelMetric, &diff4);
MagickCompareImages(magick_wand_1, magick_wand_2, MeanSquaredErrorMetric, &diff5);
MagickCompareImages(magick_wand_1, magick_wand_2, PeakAbsoluteErrorMetric, &diff6);
MagickCompareImages(magick_wand_1, magick_wand_2, PeakSignalToNoiseRatioMetric, &diff7);
MagickCompareImages(magick_wand_1, magick_wand_2, RootMeanSquaredErrorMetric, &diff8);
MagickCompareImages(magick_wand_1, magick_wand_2, NormalizedCrossCorrelationErrorMetric, &diff8);
MagickCompareImages(magick_wand_1, magick_wand_2, FuzzErrorMetric, &diff10);
MagickCompareImages(magick_wand_1, magick_wand_2, UndefinedErrorMetric, &diff11);
MagickCompareImages(magick_wand_1, magick_wand_2, PerceptualHashErrorMetric, &diff12);
NSLog(@"UndefinedMetric: %.21f", diff1);
NSLog(@"AbsoluteErrorMetric: %.21f", diff2);
NSLog(@"MeanAbsoluteErrorMetric: %.21f", diff3);
NSLog(@"MeanErrorPerPixelMetric: %.21f", diff4);
NSLog(@"MeanSquaredErrorMetric: %.21f", diff5);
NSLog(@"PeakAbsoluteErrorMetric: %.21f", diff6);
NSLog(@"PeakSignalToNoiseRatioMetric: %.21f", diff7);
NSLog(@"RootMeanSquaredErrorMetric: %.21f", diff8);
NSLog(@"NormalizedCrossCorrelationErrorMetric: %.21f", diff9);
NSLog(@"FuzzErrorMetric: %.21f", diff10);
NSLog(@"UndefinedErrorMetric: %.21f", diff11);
NSLog(@"PerceptualHashErrorMetric: %.21f", diff12);
DestroyMagickWand(magick_wand_1);
DestroyMagickWand(magick_wand_2);
DestroyMagickWand(magick_wand_3);
MagickWandTerminus();
}
5 наблюдайте вывод в отладчике (очевидно, вам понадобится другой метод, который использует какой-то монитор "threshhold", чтобы определить, какой уровень показывает "точное или близкое к совпадению", и то, что вы считаете матч себя). Кроме того, ОЧЕНЬ ВАЖНОЕ ЗАМЕЧАНИЕ, причина, по которой у меня есть переменная size_t для размера в вышеперечисленных методах, заключается в том, что вы не можете сравнивать изображения разных размеров, поэтому сначала вы должны изменить размер изображений, сравнимых с размером, который вы чувствуете "разумно", а затем оба изображения будут изменены с помощью ImageMagick, а затем сравните изображения:
Пример 1:
[self compareTwoImages:[UIImage imageNamed:@"book.png"]
secondImage:[UIImage imageNamed:@"book.png"]
comparitorSize:32];
[76233: 1364823] UndefinedMetric: 0.866871957624008593335
[76233: 1364823] AbsoluteErrorMetric: 0.000000000000000000000
[76233: 1364823] Среднее значениеAbsoluteErrorMetric: 0.000000000000000000000
[76233: 1364823] Среднее значениеErrorPerPixelMetric: 0.000000000000000000000 **
[76233: 1364823] Среднее значениеSquaredErrorMetric: 0.000000000000000000000
[76233: 1364823] PeakAbsoluteErrorMetric: 0.000000000000000000000
[76233: 1364823] PeakSignalToNoiseRatioMetric: inf
[76233: 1364823] RootMeanSquaredErrorMetric: 0.866871957624008593335
[76233: 1364823] NormalizedCrossCorrelationErrorMetric: +0,000000000000000000000
[76233: 1364823] FuzzErrorMetric: 0.000000000000000000000
[76233: 1364823] UndefinedErrorMetric: 0.866871957624008593335
[76233: 1364823] PerceptualHashErrorMetric: 0.000000000000000000000
Пример 2:
[self compareTwoImages:[UIImage imageNamed:@"book.png"]
secondImage:[UIImage imageNamed:@"arrow.png"]
comparitorSize:32];
[76338: 1368754] UndefinedMetric: 0.074585376822533272501
[76338: 1368754] AbsoluteErrorMetric: 795.000000000000000000000
[76338: 1368754] MeanAbsoluteErrorMetric: 0.314410045058480136504
[76338: 1368754] MeanErrorPerPixelMetric: 328395.000000000000000000000
[76338: 1368754] MeanSquaredErrorMetric: 0.245338692857198115149
[76338: 1368754] PeakAbsoluteErrorMetric: 1.000000000000000000000000
[76338: 1368754] PeakSignalToNoiseRatioMetric: 6.102339529383479899138
[76338: 1368754] RootMeanSquaredErrorMetric: 0.074585376822533272501
[76338: 1368754] NormalizedCrossCorrelationErrorMetric: 0.000000000000000000000
[76338: 1368754] FuzzErrorMetric: 0.571942529580490965913
[76338: 1368754] UndefinedErrorMetric: 0.074585376822533272501
[76338: 1368754] PerceptualHashErrorMetric: 1827.005561849247442296473
Здесь довольно много происходит математически. У меня нет времени объяснять все эти переменные, но достаточно сказать, что это сравнение между двумя изображениями использует некоторые очень известные методы для сравнения двух изображений. Вам придется забрать это отсюда и проверить статистику, чтобы настроить это по своему усмотрению и выбрать порог ошибки, который подходит для ваших целей.
Краткое описание:
ImageMagick - это обработанная битками библиотека обработки изображений, и хотя эти методы, перечисленные выше, являются своего рода "черным ящиком", это черная шкала, которая позволяет вам экономить время и перемещаться к чему-то, что использует OpenCV. ImageMagick уже установил некоторые очень хорошие алгоритмы обработки изображений, и эта история вместе с готовым "этим методом" работает, что является одним из самых больших преимуществ ImageMagick, учитывая то, что вам понадобится для разработки собственного образа библиотеку распознавания/обработки или методы. (кстати, я не связан с ImageMagick, я просто очень доволен продуктом, что все)
Методы, используемые в выше описанных выше методах Objective-C, - это методы, которые основаны на библиотеке ImageMagick для IOS. Вам нужно будет прочитать эти методы, но так, чтобы вы знали, они написаны на C, а не Objective-C, что означает, что некоторые из них являются чуждыми для запуска миллионного Image I/O или других библиотек обработки, Тем не менее, единственная часть, которую я вижу как трудно понять (при условии, что человек не знаком с кодом C), заключается в том, как понять, что такое "&". символ перед некоторыми переменными. Кроме этого, возникает проблема объявления и использования структур, но на это можно легко ответить, используя Stack Overflow, там много информации об этом прямо здесь.
Мне не нравится идея, что вам нужно написать собственную библиотеку или алгоритмы обработки изображений для такого приложения. Я думаю, что вы делаете очень хорошо для нуждающегося человека, и я думаю, что это поможет большому количеству людей, если вы можете заблокировать MVP, и я думаю, что использование ImageMagick поможет вам добраться туда намного раньше, чем необходимо переписать некоторые вещи, которые ImageMagick уже делает для ваших собственных целей.
Последнее замечание: ImageMagick построен на некоторых очень низких библиотеках C. Мне нужно было бы выполнить какое-то сравнение обработки, чтобы определить, насколько хорошо ImageMagick работает на устройствах IOS, чем что-то вроде Image I/O. Тем не менее, я чувствую, что эти две библиотеки обработки изображений используют одни и те же функции обработки и скорости обработки изображений. Исправьте меня, если кто-то уверен, что Image I/O определенно быстрее в тестах, но я просто говорю вам об этом, чтобы вы знали, что это НЕ ваша средняя установка POD, это надежный кусок машинного перевода, который по достоинству некоторые разработчики IOS создали версию IOS, в основном, используя CoccoaPods. Помимо этого, ImageMagick используется на всех вычислительных платформах и в основном является инструментом командной строки
Статистика, что означают цифры:
Здесь ресурсы, которые вам понадобятся, чтобы понять математику за статистикой, которую я показываю выше в отладчике:
Этот первый старый, но все же релевантный:
http://www.ict.griffith.edu.au/anthony/info/graphics/image_comparing
Этот, кажется, обновлен:
http://www.imagemagick.org/Usage/compare/
Если вы решите использовать эту библиотеку, удачи вам, мне нравится, где вы собираетесь с этим приложением, и ваше демо выглядит потрясающе!
EDIT: Я почти забыл рассказать вам о самой важной части здесь. Если статистика вернет все "нули" для всего, кроме "UndefinedMetric", "PeakSignalToNoiseRatioMetric", "RootMeanSquaredErrorMetric" и "UndefinedErrorMetric", тогда у вас БОЛЬШЕ, чем, вероятно, есть MATCH!