Skip to content

Instantly share code, notes, and snippets.

@kumarkrishna
Created December 2, 2013 20:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kumarkrishna/7758213 to your computer and use it in GitHub Desktop.
Save kumarkrishna/7758213 to your computer and use it in GitHub Desktop.
Non-recursive blobDetection using queue . Centroid also implemented
//Author :Kumar Krishna Agarwal
//Mail :kumar.1994.14@gmail.com
#include <stdio.h>
#include <highgui.h>
#include <cv.h>
#include <cxcore.h>
#include <stdio.h>
#include <stdlib.h>
#define PIX(img,i,j,k) (((uchar*)img->imageData)[(i)*img->widthStep+(j)*img->nChannels+(k)])
typedef struct node
{
int x;
int y;
struct node *next;
}node;
node *rear,*front;
int isEmpty()
{
if(front==NULL)
return 1;
else return 0;
}
void enqueue(int x,int y)
{
node* t;
t=(node*)malloc(sizeof(node));
t->x=x;
t->y=y;
t->next=NULL;
if(isEmpty())
{
front=t;
rear=front;
}
else{
rear->next=t;
rear=t;
rear->next=NULL;
}
}
void queuefront(int *x,int *y)
{
*x=front->x;
*y=front->y;
return;
}
void dequeue()
{
node* t;
if(isEmpty())
{
printf("Queue Underflow\n");
return;
}
t=front;
front=t->next;
free(t);
}
IplImage* img;
int** blobDetection(IplImage *img,int *count)
{
int i,j,k,l,x,y;
*count=0;
int height = img->height;
int width = img->width;
int **visited;
visited = (int**)malloc(height*sizeof(int*));
for(i=0;i<img->height;i++)
visited[i]=(int*)malloc(img->width*sizeof(int));
for(i=0;i<img->height;i++)
for(j=0;j<img->width;j++)
visited[i][j]=-1;
for(i=1;i<img->height-1;i++)
for(j=1;j<img->width-1;j++)
{
if(PIX(img,i,j,0)==0)
{
if(visited[i][j]==-1)
{
*count=*count +1;
front=NULL;
enqueue(i,j);
queuefront(&x,&y);
while(!isEmpty())
{
queuefront(&x,&y);
//printf("(%d,%d),(%d)",x,y,visited[x][y]);
dequeue();
for(k=x-1;k<=x+1;k++)
for(l=y-1;l<=y+1;l++)
{
if(PIX(img,k,l,0)==0 && visited[k][l]==-1)
{
enqueue(k,l);
visited[k][l]=*count;
}
}
visited[x][y]=*count;
}
}
}
}
//printf("%d\n",*count);
return visited;
}
void binary_convert(IplImage *img)
{
int i,j;
CvScalar pixel;
for(i=0;i<img->height;i++)
{
for(j=0;j<img->width;j++)
{
pixel=cvGet2D(img,i,j);
if(pixel.val[0]>100)
{
PIX(img,i,j,0)=255;
}
else
{
PIX(img,i,j,0)=0;
}
}
}
//cvNamedWindow("win",0);
//cvShowImage("win",img);
//cvWaitKey(0);
}
void centroid(int** output,int count)
{
int i,j;
double count_x[count+1];
double count_y[count+1];
double count_pixel[count+1];
for(i=0;i<img->height;i++)
{
for(j=0;j<img->width;j++)
{
int value;
value=output[i][j];
if(value!=-1)
{
count_x[value]+=j;
count_y[value]+=i;
count_pixel[value]++;
}
}
}
for(i=1;i<count+1;i++)
{
count_x[i]/=count_pixel[i];
count_y[i]/=count_pixel[i];
}
for(i=1;i<count+1;i++)
{
printf("For blob %d centroid is, x = %lf and y = %lf\n",i,count_x[i],count_y[i]);
//count_y[i]/=count_pixel[i];
}
}
int main()
{
IplImage* out;
int** output=NULL;
int count=0;
int i,j;
img=cvLoadImage("shapes.jpg",0);
//out=cvCreateImage(cvGetSize(img),img->depth,1);
binary_convert(img); //Convert image to binary
output=blobDetection(img,&count); //Blob detection
printf("count = %d\n",count);
cvShowImage("window",img);
centroid(output,count); //Centroid Callback function
cvWaitKey(0);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment