/** * Opencircle Detection Program * * This program detects open circles in Images, it returns the coordinates * to the most likely open circle for a given image file. It uses the Hugh * Transformation implemenation of the Camellia Library. * $ g++ -g -O2 -L/usr/local/lib/ -lCamellia opencircle.cpp * You must customize the configuration properties! * * Todo(but I'm not doing it :>) * - seperation (can't detect overlap circles atm) * - config file * - filled pixel percent threshold * * Author: apoc [http://4poc.org/] * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include "camellia.h" using namespace std; struct circle { int x; int y; int conf; int fill_pixels; }; // this function detects a single circle, and remove it from image circle detect_circle(CamImage *image, int percent, int rmin, int rmax) { CamImage yuv; image->to_yuv(yuv); CamROI roi(1, 0, 0, image->width-1, image->height-1); yuv.set_roi(roi); yuv.fixed_filter(CAM_GAUSSIAN_3x3); // enhance detection quality int x,y,r, conf; conf = yuv.hough_circle(percent, rmin, rmax, x, y, r); image->draw_circle(x,y,r,CAM_RGB(0,0,0)); image->fill_color(x,y,CAM_RGB(0,0,0)); image->fill_color(x,y,CAM_RGB(255,255,255)); circle ret; ret.x = x; ret.y = y; ret.conf = conf; return ret; } int fill_test(CamImage image, int x, int y, int fill_tolerance) { return image.fill_color(x, y, CAM_RGB(0,0,0), fill_tolerance); } int main(int argc, char **argv) { if(argc != 2) { cout << "Syntax: " << argv[0] << " [BMP-Filename]" << endl; return 0; } char *filename = argv[1]; /********************* CONFIGURATION *******************************/ int circle_max = 8; /*** The Numbers of Circles to look for ***/ int hough_rmin = 5; /*** Hough Transf. Minimum Circle Radius to look for ***/ /*** ***/ int hough_rmax = 20; /*** Hough Transf. Maximum Circle Radius to look for ***/ int hough_pperc = 60; /*** Percent of Pixels in Image to consider ***/ int fill_tolerance = 1; /*** Tolerance Argument for camFillColor ***/ int threshold_conf = 10; /*** Threshold of Hough Confidence return value ****/ // TODO: MAYBE: int threshold_fill_perc = 10; /*** Threshold Percent of fill Pixels ****/ CamImage image, fill_image; image.load_bmp(filename); fill_image.load_bmp(filename); // strange but copy method doesn't work circle circle_array[circle_max]; for(int i = 0; i < circle_max; i++) { circle_array[i] = detect_circle(&image, hough_pperc, hough_rmin, hough_rmax); circle_array[i].fill_pixels = fill_test(fill_image, circle_array[i].x, circle_array[i].y, fill_tolerance); } int max_fill_pixels = 0, max_i = 0; for(int i = 0; i < circle_max; i++) { if((circle_array[i].conf >= threshold_conf) && (circle_array[i].fill_pixels > max_fill_pixels)) { max_i = i; max_fill_pixels = circle_array[i].fill_pixels; } } cout << circle_array[max_i].x << "," << circle_array[max_i].y << endl; /* DEBUG fill_image.draw_circle(circle_array[max_i].x,circle_array[max_i].y,20,CAM_RGB(255,0,255)); fill_image.draw_circle(circle_array[max_i].x,circle_array[max_i].y,19,CAM_RGB(255,0,255)); fill_image.save_bmp(filename); */ return 0; }