alexs 0 Жалоба Опубликовано June 5, 2011 А есть ли в OpenCV majority фильтр, наподобие такого? Нужно выполнить "сглаживание" растра. Пробовал реализовать комбинируя dilate и erode, но они не совсем подходят. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
alexs 0 Жалоба Опубликовано June 9, 2011 Сам и отвечаю. В OpenCV нет majority фильтра, равно как и многих других вещей :-(. Наиболее близкий вариант medianBlur, но все равно не то. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Nuzhny 243 Жалоба Опубликовано June 9, 2011 Он довольно прост. Если хочешь, могу реализовать его. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
alexs 0 Жалоба Опубликовано June 9, 2011 Он довольно прост. Если хочешь, могу реализовать его. Если не сложно, то буду рад взглянуть на код. P.S.: тоже пробую реализовать Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Nuzhny 243 Жалоба Опубликовано June 9, 2011 Вот, набросал (ничего, что без комментариев?): bool majority_filter(IplImage* src_img, IplImage* dest_img, int filter_size) { if (!(filter_size % 2) || src_img->width != dest_img->width || src_img->height != dest_img->height || src_img->nChannels > 1 || dest_img->nChannels > 1) return false; int filter_size_2 = filter_size / 2; CvRect r = cvRect(0, 0, filter_size, filter_size); int bins = 255; int hist_size[] = { bins }; float range[] = { 0, 255 }; float* ranges[] = { range }; CvHistogram* hist = cvCreateHist(1, hist_size, CV_HIST_ARRAY, ranges, 1); for (int y = 0; y < src_img->height; ++y) { r.y = y - filter_size_2; if (r.y < 0) { r.height = filter_size + r.y; r.y = 0; } else if (r.y + filter_size > src_img->height) { r.height = src_img->height - r.y; } else r.height = filter_size; for (int x = 0; x < src_img->width; ++x) { r.x = x - filter_size_2; if (r.x < 0) { r.width = filter_size + r.x; r.x = 0; } else if (r.x + filter_size > src_img->width) { r.width = src_img->width - r.x; } else r.width = filter_size; cvSetImageROI(src_img, r); cvCalcHist(&src_img, hist, 0, 0); int max1 = 0, max2 = 0; int ind1 = 0, ind2 = 0; for (int i = 0; i < bins; ++i) { CvScalar v = cvGet1D(hist->bins, i); if ((int)v.val[0] >= max1) { max2 = max1; ind2 = ind1; max1 = (int)v.val[0]; ind1 = i; } } cvResetImageROI(src_img); if (max1 > max2) cvSet2D(dest_img, y, x, cvScalar(ind1)); } } cvReleaseHist(&hist); return true; } //////////////////////////////////////////////////////////////////////////// void print_img(const IplImage* img) { for (int y = 0; y < img->height; ++y) { for (int x = 0; x < img->width; ++x) { CvScalar v = cvGet2D(img, y, x); printf("% 4.0f ", v.val[0]); } printf("\n"); } printf("\n"); } //////////////////////////////////////////////////////////////////////////// int _tmain(int argc, _TCHAR* argv[]) { cvNamedWindow("before", 0); cvNamedWindow("after", 0); #if 0 IplImage* img1 = cvLoadImage("D:\\video_bmp\\black_23.jpg", 0); #else IplImage* img1 = cvCreateImage(cvSize(6, 6), 8, 1); char data[] = { 4, 4, 4, 4, -3, 7, 0, 0, \ 4, 4, 7, 7, 7, 7, 0, 0, \ 5, 5, 7, 7, 6, 7, 0, 0, \ 5, 5, 5, 5, 5, 6, 0, 0, \ 7, 7, 5, 5, 5, 5, 0, 0, \ 7, 0, 5, 2, 0, 0, 0, 0 }; memcpy(img1->imageData, data, sizeof(data)); #endif cvShowImage("before", img1); IplImage* img2 = cvCloneImage(img1); majority_filter(img1, img2, 3); cvShowImage("after", img2); print_img(img1); print_img(img2); cvWaitKey(0); cvReleaseImage(&img1); cvReleaseImage(&img2); cvDestroyAllWindows(); return 0; } //////////////////////////////////////////////////////////////////////////// В качестве примера я брал и обычные изображения (однотонные, gray), и пример из твоей ссылки. Результат выводится в консоль, совпадает с результатом по ссылке, который находится под чертой. Я правильно понимаю, что по изображению просто проходят каким-то окном (нечётного размера), находят максимально встречающееся значение и присваивают в текущую позицию? Если да, то ответ по ссылке не совсем правильный: в верхней строке, четвёртый элемент должен быть "7", так как вокруг него находится две "4", три "7" и одна "-3". Так же? 1 Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано June 10, 2011 есть еще фильтр кувахара(kuwahara filter)- сохраняющий грани сглаживающий фильтр. пример работы http://rsbweb.nih.gov/ij/plugins/kuwahara.html 1 Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
alexs 0 Жалоба Опубликовано June 10, 2011 Вот, набросал (ничего, что без комментариев?): Огромное спасибо, буду разбираться. Отсутствие комментариев не помеха. Я правильно понимаю, что по изображению просто проходят каким-то окном (нечётного размера), находят максимально встречающееся значение и присваивают в текущую позицию? Если да, то ответ по ссылке не совсем правильный: в верхней строке, четвёртый элемент должен быть "7", так как вокруг него находится две "4", три "7" и одна "-3". Так же? Да, все верно. По поводу ошибки в документации — все может быть, сейчас гляну и если что, закину багрепорт. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах