ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
hey firstfire,
i have got the code from the same page u hav suggested for canny edge detection.
i want to perform circular hough transform of the image after canny
Code:
#include <math.h>
#include "array.h"
#define PI 3.1415926
main(int argc, char *argv[])
{
BYTE **in_img, **out_img, **hough_img;
int nrows, ncols, nrho, ntheta, x, y;
double **hough, thresh, theta, rho, rad, max, alpha;
if (argc != 6) {
printf("Usage: %s <nrows> <ncols> <thresh> <in_img> <out_img>\n", argv[0]);
exit(0);
}
nrows = atoi(argv[1]);
ncols = atoi(argv[2]);
nrho = (int)sqrt(nrows*nrows+ncols*ncols) + 1;
ntheta = 271; // -90 ~ 180
thresh = atof(argv[3]);
rad = PI/180;
max = 0;
in_img = new_byte_array(nrows, ncols);
read_byte_array(argv[4], in_img, nrows, ncols);
hough = new_double_array(nrho, ntheta);
hough_img = new_byte_array(nrho, ntheta);
out_img = new_byte_array(nrows, ncols);
// Initialize Hough array
for (x=0; x<nrho; x++)
for (y=0; y<ntheta; y++)
hough[x][y] = 0;
for (x=0; x<nrows; x++)
for (y=0; y<ncols; y++)
if (in_img[x][y] == 255)
for (theta= -90; theta<=180; theta++) {
rho = x*cos(theta*rad) + y*sin(theta*rad);
if (rho>0 && rho<nrho) { // Solution of rho found.
hough[(int)rho][(int)(theta+90)]++;
if (max < hough[(int)rho][(int)(theta+90)])
max = hough[(int)rho][(int)(theta+90)];
}
}
// Normalize to the range of [0, 255]
alpha = 255/max;
for (x=0; x<nrho; x++)
for (y=0; y<ntheta; y++)
hough_img[x][y] = (BYTE)(alpha*hough[x][y]);
write_byte_array("Hough.raw", hough_img, nrho, ntheta);
printf("'Hough.raw' (%d x 271) created\n", nrho);
for (x=0; x<nrows; x++)
for (y=0; y<ncols; y++) {
out_img[x][y] = 0;
// The following 'if' statement can be commented to see straight lines
// if (in_img[x][y] != 255)
// continue;
for (theta=-90; theta<180; theta++) {
rho = x*cos(theta*rad) + y*sin(theta*rad);
if (rho>0 && rho<nrho && hough[(int)rho][(int)(theta+90)]>thresh)
out_img[x][y] = 255;
}
}
write_byte_array(argv[5], out_img, nrows, ncols);
}
IFAIK this code does linear Hough transform. Of course you can grasp some ideas from it, but it is not for circular transform. Main difference is that Hough space for linear transform is two(2)-dimentional, while Hough space for circular transform is three(3)-dimentional.
hi,
can u plz suggest any modification with this code so that i can convert i into circular.. i knw very little abt circular hough transform and also didn't able to find any program for it..
The ugly code below, when called, tries to find circle in input image and draws a cross in its center:
Code:
void cross(pixel_t *in, BITMAPINFOHEADER *ih, int x, int y)
{
int i, Nx=10, Ny=10;
for(i=x-Nx; i<=x+Nx; i++) in[i+ih->width*y] = 255;
for(i=y-Ny; i<=y+Ny; i++) in[x+ih->width*i] = 255;
}
#include <limits.h>
void circular_hough_transform(pixel_t *in, BITMAPINFOHEADER *ih, int T1, int T2)
{
int nx = ih->width;
int ny = ih->height;
unsigned long long i, j, k, l, x0, y0,
r2, // = r^2
nx0 = nx,
ny0 = ny,
N = nx0*ny0,
nr2 = 50, // quite random choice
r2max = pow( fmax(nx, ny) , 2);
fprintf(stderr, "circular Hough space size %llu; r2max=%d\n", nx*ny*nr2, r2max);
unsigned short *out = calloc(nx0*ny0*nr2, sizeof(unsigned short));
if(!out){
perror("circular_hough_transform()");
exit(1);
}
for(j=0; j<ny; j++)
for(i=0; i<nx; i++) {
if(in[i+nx*j] < T1) continue;
for(y0=0; y0<ny0; y0++) {
for(x0=0; x0<nx0; x0++) {
r2 = (i-x0)*(i-x0) + (j-y0)*(j-y0);
if(r2 > r2max || r2 < 1) continue;
r2 = floor(r2*nr2/r2max);
k = x0 + nx0 * y0 + N * r2;
if(out[k] < USHRT_MAX)
out[k]++;
}
}
}
int counter = 0;
// Find maximums in the out array.
for(y0=0; y0<ny0; y0++)
for(x0=0; x0<nx0; x0++)
for(r2=0; r2<nr2; r2++)
if( out[x0 + nx0 * y0 + N * r2] > T2)
{
printf("%d:\tx0=%d\ty0=%d\tr=%g\n",
counter++, (int)x0, (int)y0, sqrt(r2*r2max/(double)nr2));
cross(in, ih, x0, y0);
}
free(out);
}
It works only on small images, say 200x200 pixels, requires to specify sensible threshold values T1, T2, and is very slow. It crashes on lena512. I don't think the circular Hough transform is practical in this form.
the program that u have posted for circular hough transform,i have tried it for 200*200 pixel,,,,bt its showing a warning
Quote:
format '%d' expects type 'int',but argument 4 has type 'long long unsigned int'
......hence its showing a segmentation fault at runtym.
reguards.
This warning has nothing to do with segmentation fault. You can replace `%d' by `%lld' to remove the warning. Or remove that line completely.
Quote:
also if i run the program with a 8 bit image and of 512x512 dimeantion then itz not showing any segmentation fault.
itz givind the result
Quote:
circular hough space size=13107200;r2max=262144
bt here itz nt showin any image.. i mean out.bmp is not created,,
thank u.
Are you sure the program finishes correctly for such dimensions? As I mentioned, lena512.bmp causes core dump (crashes) after a long delay on my machine and no out.bmp created. I did not tried to figure out the reasons.
fread(&mag,sizeof(struct bmpfile_magic),1,filePtr);
//verify that this is a bmp file by check bitmap id
if(*((uint16_t*) mag.magic)!=0x4D42)
{
fprintf(stderr,"Not a bmp file:magic=%c%c\n",mag.magic[0],mag.magic[1]);
fclose(filePtr);
return NULL;
}
//read the bitmap header
fread(&bitmapFileHeader,sizeof(struct bmpfile_header),1,filePtr);
//read the bitmap info header
fread(bitmapInfoHeader,sizeof(BITMAPINFOHEADER),1,filePtr);
if(bitmapInfoHeader->compress_type!=0)
fprintf(stderr,"Warning,compression is not supported.\n");
//move file point to the beginning of bitmap data
fseek(filePtr,bitmapFileHeader.bmp_offset,SEEK_SET);
//allocate enough memory for bitmao image data
bitmapImage=(pixel_t*)malloc(bitmapInfoHeader->bmp_bytesz*(sizeof(pixel_t)));
//verify memory allocation
if(!bitmapImage)
{
free(bitmapImage);
fclose(filePtr);
return NULL;
}
//read in the bitmap image data
int i;
unsigned char c;
for( i=0;i<bitmapInfoHeader->bmp_bytesz;i++){
fread(&c,sizeof(unsigned char),1,filePtr);
bitmapImage[i]=(int)c;
}
fclose(filePtr);
return bitmapImage;
}
itz a 8 bit image bt when we reduce itz size to 200x200 then the program is giving a segmentation fault...
i am doing with a image of nano particles of 8bit and dimension 512X512
thank u
Hi.
Here is an example image (200x200x8) I use for tests: circ.bmp.txt (remove the '.txt' suffix)
And here is an output produced by the above program with Hough threshold T2=220 (I modified function cross() so that the size of cross equals actual radius of circle):
I do not observe segmentation fault. If output image is blank, then try to decrease thresholds in Canny and Hough.
hi firstfire'
can u plz xplain me ur logic of modifying the function cross()........where should we change the value of canny and hough???.is it in the main part or any other part?..what are the modifications that r needed while using the image lena512.bmp,,bcoz our pic specification is the same to that of lena512..
reguards...
You should first find appropriate pair of thresholds for Canny filter (without Hough to save time) so that output image contains edges you are interested in. Then you should try different values of second threshold in Hough transform (220 in above code snippet) so that circles you are interested in are detected. This number equals to the minimum number of pixels on a circle for the circle to be detected.
As for the segmentation fault, I found the source of all evil -- it is a cross() function, I did not checked for array boundary violation. Here is a new version
Code:
void cross(pixel_t *in, BITMAPINFOHEADER *ih, int x, int y, int r)
{
int i, Nx=r, Ny=r;
int xmin = (x-Nx>0) ? x-Nx : 0,
xmax = (x+Nx<ih->width) ? x+Nx : ih->width-1,
ymin = (y-Ny>0) ? y-Ny : 0,
ymax = (y+Ny<ih->height) ? y+Ny : ih->height-1;
for(i=xmin; i<=xmax; i++) in[i+ih->width*y] = 255;
for(i=ymin; i<=ymax; i++) in[x+ih->width*i] = 255;
}
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.