Перейти к содержимому
Compvision.ru

Доска почета


Popular Content

Showing most liked content on 09.06.2011 во всех областях

  1. 1 point
    Вот, набросал (ничего, что без комментариев?): 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". Так же?
  2. 1 point
    Zhang-Suen algorithm. http://xa.yimg.com/kq/groups/1986690/749653118/name/skeleton.c #include <OpenCV/cv.h> #include <OpenCV/highgui.h> #define NORTH 1 #define SOUTH 3 void skeletonize(IplImage *src); int main (int argc, char * const argv[]) { IplImage *image = 0, *srcCopy = 0; int w, h, i, j, r, g, b; CvScalar pixel, pixOut; if(argc != 2) { printf("Usage: skeletonize <image_file>\n"); exit(1); } image = cvLoadImage(argv[1], CV_LOAD_IMAGE_GRAYSCALE); //image = cvLoadImage(argv[1], 1); if (!image) { printf("Can't find %s\n", argv[1]); exit(1); } w = image->width; h = image->height; //srcCopy = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 3); srcCopy = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1); for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { pixel = cvGet2D(image, i, j); b = pixel.val[0]; if (b > 50) pixOut.val[0] = 255; else pixOut.val[0] = 0; cvSet2D(srcCopy, i, j, pixOut); } } skeletonize(srcCopy); cvNamedWindow("Original", CV_WINDOW_AUTOSIZE); cvMoveWindow("Original", 100, 100); cvShowImage("Original", image); cvNamedWindow("Skeleton", CV_WINDOW_AUTOSIZE); cvMoveWindow("Skeleton", 150, 150); cvShowImage("Skeleton", srcCopy); cvWaitKey(0); // Release images' buffers... cvReleaseImage(&image); cvReleaseImage(&srcCopy); //...and windows cvDestroyWindow("Original"); cvDestroyWindow("Skeleton"); return 0; } // 1-neighbors of pixel. int nays8(IplImage *im, int r, int c) { CvScalar pixel; int blue, k = 0, i, j; for (i = r-1; i <= r+1; i++) for (j = c-1; j <= c+1; j++) if (i != r || c != j) { pixel = cvGet2D(im, i, j); blue = pixel.val[0]; if (blue >= 1) k++; } return k; } int connectivity(IplImage *im, int r, int c) { int N = 0, b1, b2; CvScalar pixel; pixel = cvGet2D(im, r, c+1); b1 = pixel.val[0]; pixel = cvGet2D(im, r-1, c+1); b2 = pixel.val[0]; if (b1 >= 1 && b2 == 0) N++; pixel = cvGet2D(im, r-1, c+1); b1 = pixel.val[0]; pixel = cvGet2D(im, r-1, c); b2 = pixel.val[0]; if (b1 >= 1 && b2 == 0) N++; pixel = cvGet2D(im, r-1, c); b1 = pixel.val[0]; pixel = cvGet2D(im, r-1, c-1); b2 = pixel.val[0]; if (b1 >= 1 && b2 == 0) N++; pixel = cvGet2D(im, r-1, c-1); b1 = pixel.val[0]; pixel = cvGet2D(im, r, c-1); b2 = pixel.val[0]; if (b1 >= 1 && b2 == 0) N++; pixel = cvGet2D(im, r, c-1); b1 = pixel.val[0]; pixel = cvGet2D(im, r+1, c-1); b2 = pixel.val[0]; if (b1 >= 1 && b2 == 0) N++; pixel = cvGet2D(im, r+1, c-1); b1 = pixel.val[0]; pixel = cvGet2D(im, r+1, c); b2 = pixel.val[0]; if (b1 >= 1 && b2 == 0) N++; pixel = cvGet2D(im, r+1, c); b1 = pixel.val[0]; pixel = cvGet2D(im, r+1, c+1); b2 = pixel.val[0]; if (b1 >= 1 && b2 == 0) N++; pixel = cvGet2D(im, r+1, c+1); b1 = pixel.val[0]; pixel = cvGet2D(im, r, c+1); b2 = pixel.val[0]; if (b1 >= 1 && b2 == 0) N++; return N; } void deleteCB(IplImage *im, IplImage *tmp) { int w, h, blue, i, j; CvScalar pixel; w = im->width; h = im->height; for (i = 1; i < h-1; i++) for (int j = 1; j < w-1; j++) { pixel = cvGet2D(tmp, i, j); blue = pixel.val[0]; if (blue == 1) { pixel.val[0] = 0; cvSet2D(im, i, j, pixel); cvSet2D(tmp, i, j, pixel); } } } void stair(IplImage *im, IplImage *tmp, int dir) { int i, j, b1, b2, b3, b4, b5, b6, b7, b8, b9, w, h; CvScalar pixel; int N, S, E, W, NE, NW, SE, SW, C; w = im->width; h = im->height; if (dir == NORTH) for (i = 1; i < h-1; i++) for (j = 1; j < w-1; j++) { pixel = cvGet2D(im, i-1, j-1); b1 = pixel.val[0]; pixel = cvGet2D(im, i-1, j); b2 = pixel.val[0]; pixel = cvGet2D(im, i-1, j+1); b3 = pixel.val[0]; pixel = cvGet2D(im, i, j-1); b4 = pixel.val[0]; pixel = cvGet2D(im, i, j); b5 = pixel.val[0]; pixel = cvGet2D(im, i, j+1); b6 = pixel.val[0]; pixel = cvGet2D(im, i+1, j-1); b7 = pixel.val[0]; pixel = cvGet2D(im, i+1, j); b8 = pixel.val[0]; pixel = cvGet2D(im, i+1, j+1); b9 = pixel.val[0]; if (b1 == 1) NW = 1; else NW = 0; if (b2 == 1) N = 1; else N = 0; if (b3 == 1) NE = 1; else NE = 0; if (b4 == 1) W = 1; else W = 0; if (b5 == 1) C = 1; else C = 0; if (b6 == 1) E = 1; else E = 0; if (b7 == 1) SW = 1; else SW = 0; if (b8 == 1) S = 1; else S = 0; if (b9 == 1) SE = 1; else SE = 0; if (dir == NORTH) { if (C && !(N && ((E && !NE && !SW && (!W || !S)) || (W && !NW && !SE && (!E || !S))))) { pixel.val[0] = 0; cvSet2D(tmp, i, j, pixel); } else { pixel.val[0] = 1; cvSet2D(tmp, i, j, pixel); } } else if (dir == SOUTH) { if (C && !(S && ((E && !SE && !NW && (!W || !N)) || (W && !SW && !NE && (!E || !N))))) { pixel.val[0] = 0; cvSet2D(tmp, i, j, pixel); } else { pixel.val[0] = 1; cvSet2D(tmp, i, j, pixel); } } } } // Zhang-Suen algorithm. void skeletonize(IplImage *im) { int janelaAH[][2] = { {1, 0}, {0, -1}, {-1, 0}, {0, 1} }; int janelaH[][2] = { {0, -1}, {1, 0}, {0, 1}, {-1, 0} }; int aBlue[6]; int w, h, i, v, j, k, blue, lin, col, iJanela, again = 1; CvScalar pixel, pixOut; IplImage *tmp = 0; w = im->width; h = im->height; tmp = cvCreateImage(cvGetSize(im), IPL_DEPTH_8U, 1); for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { pixel = cvGet2D(im, i, j); blue = pixel.val[0]; if (blue > 0) pixel.val[0] = 0; else pixel.val[0] = 1; cvSet2D(im, i, j, pixel); pixOut.val[0] = 0; cvSet2D(tmp, i, j, pixOut); } } while (again) { again = 0; for (i = 1; i < h-1; i++) for (j = 1; j < w-1; j++) { pixel = cvGet2D(im, i, j); blue = pixel.val[0]; if (blue != 1) continue; k = nays8(im, i, j); iJanela = 0; if ((k >= 2 && k <= 6) && connectivity(im, i, j) == 1) { for (v = 0; v < 6; v++) { col = j + janelaAH[iJanela][0]; lin = i + janelaAH[iJanela][1]; pixel = cvGet2D(im, lin, col); aBlue[v] = pixel.val[0]; iJanela++; if (v == 2) iJanela = 1; } if (aBlue[0]*aBlue[1]*aBlue[2] == 0 && aBlue[3]*aBlue[4]*aBlue[5] == 0) { pixOut.val[0] = 1; cvSet2D(tmp, i, j, pixOut); again = 1; } } // if ((k >= 2... } // for (j = 1;... deleteCB(im, tmp); if (!again) break; for (i = 1; i < h-1; i++) for (j = 1; j < w-1; j++) { pixel = cvGet2D(im, i, j); blue = pixel.val[0]; if (blue != 1) continue; k = nays8(im, i, j); iJanela = 0; if ((k >= 2 && k <= 6) && connectivity(im, i, j) == 1) { for (v = 0; v < 6; v++) { col = j + janelaH[iJanela][0]; lin = i + janelaH[iJanela][1]; pixel = cvGet2D(im, lin, col); aBlue[v] = pixel.val[0]; iJanela++; if (v == 2) iJanela = 1; } if (aBlue[0]*aBlue[1]*aBlue[2] == 0 && aBlue[3]*aBlue[4]*aBlue[5] == 0) { pixOut.val[0] = 1; cvSet2D(tmp, i, j, pixOut); again = 1; } } // if ((k >= 2... } // for (j = 1;... deleteCB(im, tmp); } // while stair(im, tmp, NORTH); deleteCB(im, tmp); stair(im, tmp, SOUTH); deleteCB(im, tmp); for (i = 1; i < h-1; i++) for (j = 1; j < w-1; j++) { pixel = cvGet2D(im, i, j); blue = pixel.val[0]; if (blue > 0) pixel.val[0] = 0; else pixel.val[0] = 255; cvSet2D(im, i, j, pixel); } } // End skeletonize
×