tybik 0 Жалоба Опубликовано April 9, 2011 Добрый день! Помогоите пожалуйста. Стоит такая задача. Хочу улучшить картинку перед тем как отдать ее на распознавание. Нашел метод увеличения контрастности. Суть его состоит в том что: 1. Ищем самый светлый элемент и самый темный. (max и min) 2. Смотрим на сколько они отличаются от максимально возможных вариантов яркости элементов. 3. Заменяем наш max на самый яркий элемент, min на минимально яркий.. (тоесть по сути раздвигаем гистограмму) Как это лучше реализовать в OpenCV как получить доступ к пикселю в IplImage? Может у кого то есть другие предложения как можно улучшить картинку? Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано April 9, 2011 Добрый день! Помогоите пожалуйста. Стоит такая задача. Хочу улучшить картинку перед тем как отдать ее на распознавание. Нашел метод увеличения контрастности. Суть его состоит в том что: 1. Ищем самый светлый элемент и самый темный. (max и min) 2. Смотрим на сколько они отличаются от максимально возможных вариантов яркости элементов. 3. Заменяем наш max на самый яркий элемент, min на минимально яркий.. (тоесть по сути раздвигаем гистограмму) Как это лучше реализовать в OpenCV как получить доступ к пикселю в IplImage? Может у кого то есть другие предложения как можно улучшить картинку? Смотреть тут (Step 3): Histogram Equalization Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Nuzhny 243 Жалоба Опубликовано April 9, 2011 Эквализация гистограммы - это хорошо, но не всегда. Если изображение пожато, то в результате могут явно проявиться артефакты сжатия. Особенно это заметно на потоковых кодеках. В этом случае надо предварительно избавляться от артефактов и лишь после улучшать контрастность. Кроме контрастности, можно ещё улучшить резкость: найти лапласиан от яркости и сложить с исходным изображением. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано April 9, 2011 Есть еще один простой метод: http://en.wikipedia.org/wiki/Unsharp_masking http://www.luminous-landscape.com/tutorials/understanding-series/understanding-usm.shtml Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
nagoHok 4 Жалоба Опубликовано July 11, 2011 А можно по конкретнее как увеличить резкость? Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано July 11, 2011 Фильтр применить, например как здесь, но вообщем случае вопрос достаточно сложный. копать по слову deblurring. PS: кстати, в Opencv вроде есть анизотропный фильтр (anisotropic filter), медленный правда, но готовый к употреблению Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Nuzhny 243 Жалоба Опубликовано July 11, 2011 Здесь посмотри пост f.kirill, примеры работы, приводимого им фильтра. 1 Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
nagoHok 4 Жалоба Опубликовано July 11, 2011 Здесь посмотри пост f.kirill, примеры работы, приводимого им фильтра. я правильно понимаю что сначало мы делаем свертку с маской 0.1111 -0.8889 0.1111 -0.8889 4.1111 -0.8889 0.1111 -0.8889 0.1111 затем полученный результат суммируем с исходным изображением? double arKernel[25] = {0.1111, -0.8889, 0.1111, -0.8889, 4.1111, -0.8889, 0.1111, -0.8889, 0.1111}; CvMat mat = cvMat(3, 3, CV_8UC1, arKernel); cvFilter2D(src, dst, &mat, cvPoint(-1,-1)); cvAdd(src, dst, dst); Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
nagoHok 4 Жалоба Опубликовано July 11, 2011 Как ни странно но результат это белый квадрат. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Nuzhny 243 Жалоба Опубликовано July 12, 2011 1. Ммм, а зачем суммировать? 2. Почему размер ядра фильтра (double arKernel[25]) 25, а не 9? Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
nagoHok 4 Жалоба Опубликовано July 12, 2011 1. Ммм, а зачем суммировать? 2. Почему размер ядра фильтра (double arKernel[25]) 25, а не 9? Опа, действительно мой косяк на счет размерности. Просто понял фразу Фильтрация лапласианом и сложение с исходным эквивалентно фильтрации фильтром: 0.1111 -0.8889 0.1111 -0.8889 4.1111 -0.8889 0.1111 -0.8889 0.1111 Всё, что выходит за пределы диапазона, обрезается. то что надо просуммировать исходное изображение с фильтрованным. Т.е. наложить данный фильтр это и есть увеличение резкости или же как говорит Smorodov не все так просто в этом вопросе? Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано July 12, 2011 Здесь похоже имеется ввиду, что обработка этим фильтром = лаплассиан изображения + само изображение. Фильтр не должен выдавать значения больше диапазона значений изображения, т.к. сумма элементов матрицы равна 0.999. Так что изображение будет на 0.1% темнее исходного. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
nagoHok 4 Жалоба Опубликовано July 12, 2011 Здесь похоже имеется ввиду, что обработка этим фильтром = лаплассиан изображения + само изображение. Фильтр не должен выдавать значения больше диапазона значений изображения, т.к. сумма элементов матрицы равна 0.999. Так что изображение будет на 0.1% темнее исходного. т.е. суммировать свернутое и исходное изображение всетаки надо? Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано July 12, 2011 Все-таки нет Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
nagoHok 4 Жалоба Опубликовано July 12, 2011 как ни странно но после свертки все равно белый квадрат double arKernel[9] = {0.1111, -0.8889, 0.1111, -0.8889, 4.1111, -0.8889, 0.1111, -0.8889, 0.1111}; CvMat mat = cvMat(3, 3, CV_8UC1, &arKernel); cvFilter2D(src, dst, &mat, cvPoint(-1,-1)); Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано July 12, 2011 Не странно. CV_8UC1 тип это не double и не float, а указатель разыменован, вот и получается чепуха. Там должен стоять CV_64FC1 Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
nagoHok 4 Жалоба Опубликовано July 13, 2011 Не странно. CV_8UC1 тип это не double и не float, а указатель разыменован, вот и получается чепуха. Там должен стоять CV_64FC1 спасибо но не помогло ) Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Nuzhny 243 Жалоба Опубликовано July 13, 2011 На изображениях с костями у меня всё нормально отрабатывает: IplImage* src = cvLoadImage("d:\\video_bmp\\test01.jpg"); double arKernel[9] = {0.1111, -0.8889, 0.1111, -0.8889, 4.1111, -0.8889, 0.1111, -0.8889, 0.1111}; CvMat mat = cvMat(3, 3, CV_64FC1, arKernel); IplImage* dst = cvCloneImage(src); cvFilter2D(src, dst, &mat, cvPoint(-1,-1)); Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах