tybik 0 Report post Posted April 9, 2011 Добрый день! Помогоите пожалуйста. Стоит такая задача. Хочу улучшить картинку перед тем как отдать ее на распознавание. Нашел метод увеличения контрастности. Суть его состоит в том что: 1. Ищем самый светлый элемент и самый темный. (max и min) 2. Смотрим на сколько они отличаются от максимально возможных вариантов яркости элементов. 3. Заменяем наш max на самый яркий элемент, min на минимально яркий.. (тоесть по сути раздвигаем гистограмму) Как это лучше реализовать в OpenCV как получить доступ к пикселю в IplImage? Может у кого то есть другие предложения как можно улучшить картинку? Share this post Link to post Share on other sites
Smorodov 578 Report post Posted April 9, 2011 Добрый день! Помогоите пожалуйста. Стоит такая задача. Хочу улучшить картинку перед тем как отдать ее на распознавание. Нашел метод увеличения контрастности. Суть его состоит в том что: 1. Ищем самый светлый элемент и самый темный. (max и min) 2. Смотрим на сколько они отличаются от максимально возможных вариантов яркости элементов. 3. Заменяем наш max на самый яркий элемент, min на минимально яркий.. (тоесть по сути раздвигаем гистограмму) Как это лучше реализовать в OpenCV как получить доступ к пикселю в IplImage? Может у кого то есть другие предложения как можно улучшить картинку? Смотреть тут (Step 3): Histogram Equalization Share this post Link to post Share on other sites
Nuzhny 243 Report post Posted April 9, 2011 Эквализация гистограммы - это хорошо, но не всегда. Если изображение пожато, то в результате могут явно проявиться артефакты сжатия. Особенно это заметно на потоковых кодеках. В этом случае надо предварительно избавляться от артефактов и лишь после улучшать контрастность. Кроме контрастности, можно ещё улучшить резкость: найти лапласиан от яркости и сложить с исходным изображением. Share this post Link to post Share on other sites
Smorodov 578 Report post Posted April 9, 2011 Есть еще один простой метод: http://en.wikipedia.org/wiki/Unsharp_masking http://www.luminous-landscape.com/tutorials/understanding-series/understanding-usm.shtml Share this post Link to post Share on other sites
nagoHok 4 Report post Posted July 11, 2011 А можно по конкретнее как увеличить резкость? Share this post Link to post Share on other sites
Smorodov 578 Report post Posted July 11, 2011 Фильтр применить, например как здесь, но вообщем случае вопрос достаточно сложный. копать по слову deblurring. PS: кстати, в Opencv вроде есть анизотропный фильтр (anisotropic filter), медленный правда, но готовый к употреблению Share this post Link to post Share on other sites
Nuzhny 243 Report post Posted July 11, 2011 Здесь посмотри пост f.kirill, примеры работы, приводимого им фильтра. 1 Share this post Link to post Share on other sites
nagoHok 4 Report post Posted 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); Share this post Link to post Share on other sites
nagoHok 4 Report post Posted July 11, 2011 Как ни странно но результат это белый квадрат. Share this post Link to post Share on other sites
Nuzhny 243 Report post Posted July 12, 2011 1. Ммм, а зачем суммировать? 2. Почему размер ядра фильтра (double arKernel[25]) 25, а не 9? Share this post Link to post Share on other sites
nagoHok 4 Report post Posted 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 не все так просто в этом вопросе? Share this post Link to post Share on other sites
Smorodov 578 Report post Posted July 12, 2011 Здесь похоже имеется ввиду, что обработка этим фильтром = лаплассиан изображения + само изображение. Фильтр не должен выдавать значения больше диапазона значений изображения, т.к. сумма элементов матрицы равна 0.999. Так что изображение будет на 0.1% темнее исходного. Share this post Link to post Share on other sites
nagoHok 4 Report post Posted July 12, 2011 Здесь похоже имеется ввиду, что обработка этим фильтром = лаплассиан изображения + само изображение. Фильтр не должен выдавать значения больше диапазона значений изображения, т.к. сумма элементов матрицы равна 0.999. Так что изображение будет на 0.1% темнее исходного. т.е. суммировать свернутое и исходное изображение всетаки надо? Share this post Link to post Share on other sites
Smorodov 578 Report post Posted July 12, 2011 Все-таки нет Share this post Link to post Share on other sites
nagoHok 4 Report post Posted 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)); Share this post Link to post Share on other sites
Smorodov 578 Report post Posted July 12, 2011 Не странно. CV_8UC1 тип это не double и не float, а указатель разыменован, вот и получается чепуха. Там должен стоять CV_64FC1 Share this post Link to post Share on other sites
nagoHok 4 Report post Posted July 13, 2011 Не странно. CV_8UC1 тип это не double и не float, а указатель разыменован, вот и получается чепуха. Там должен стоять CV_64FC1 спасибо но не помогло ) Share this post Link to post Share on other sites
Nuzhny 243 Report post Posted 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)); Share this post Link to post Share on other sites