static UNUSED IplImage*
test_find_edges_hist(IplImage *im)
{
  int w = im->width;
  int h = im->height;
  CvSize small_size = {w / 8, h / 8};
  CvPoint middle = {w/2, h/2};

  IplImage *small = cvCreateImage(small_size, IPL_DEPTH_8U, 1); /*for quicker histogram */
  IplImage *mask = cvCreateImage(cvGetSize(im), IPL_DEPTH_8U, 1);
  IplImage *green = cvCreateImage(cvGetSize(im), IPL_DEPTH_8U, 1);
  cvSplit(im, NULL, green, NULL, NULL);

  cvResize(green, small, CV_INTER_NN);
  //small = green;

  int hist_size[] = {255};
  float range[] = {0, 255};
  float *ranges[] = {range};
  CvHistogram* hist = cvCreateHist(1, hist_size, CV_HIST_ARRAY, ranges, 1);
  cvCalcHist(&small, hist, 0, NULL);

  int pixels = small->width * small->height;
  int min_black = pixels / 8;
  int max_black = pixels / 2;
  int totals[256] = {0};

  int best_d = pixels + 1;
  int best_t = 0;

  int total = 0;
  for (int i = 0; i < 255; i++){
    int v = (int)cvQueryHistValue_1D(hist, i + 2);
    total += v;
    totals[i] = total;
    if (total > min_black){
      if (i > 5){
        int diff = totals[i] - totals[i - 5];
        if (diff < best_d){
          best_d = diff;
          best_t = i;
        }
        if (total >= max_black){
          break;
        }
      }
    }
  }
  best_t -= 2;
  printf("found best threshold %d -- %d pixel change at %d/%d pixels\n",
      best_t, best_d, totals[best_t], pixels);

  cvCmpS(green, best_t, mask, CV_CMP_GT);
  IplImage *mask2 = cvCreateImage(cvGetSize(im), IPL_DEPTH_8U, 1);
  memset(mask2->imageData, 255, w*h);
  floodfill_mono_superfast(mask, mask2, middle);
  return mask2;
}
Beispiel #2
0
void range_finder(int *indx,int min, int max, CvHistogram *hist,int num_pix, float per_lost) {
	
	int i,j,z;
	float temp;
	int sum=0;
	i=min;
	j=max;
	/*for(z=0; i<=j;z++)
    {
		if(z%2==0)
		{
			sum+=cvQueryHistValue_1D(hist,i);
			i++;
		}
		else
		{
			sum+=cvQueryHistValue_1D(hist,j);
			j--;						
		}	
		if((float)sum/(float)num_pix>=(float)per_lost)
				break;	
		//fprintf(stderr,"hskin min=%d max=%d\n",1,i,j);				
	}*/
	for(i=min; i<=j;i++)
    {

		sum+=cvQueryHistValue_1D(hist,i);
		if((float)sum/(float)num_pix>=((float)per_lost/(float)2))
				break;	
		fprintf(stderr,"min=%d max=%d\n",i,j);				
	}
	sum=0;
	for(j=max; i<=j;j--)
    {

		sum+=cvQueryHistValue_1D(hist,j);

		if((float)sum/(float)num_pix>=((float)per_lost/(float)2))
				break;	
		fprintf(stderr,"min=%d max=%d\n",i,j);				
	}

	indx[0]=i;
	indx[1]=j;
}
Beispiel #3
0
//It tries to find out the class
//that frame belongs to.
//It does it using the L2 norm. It sorts the results
//and select the nearest core. If cores are empty
//it returns -1
KMeansTriple KMeans::findClass(IplImage *frame)
{	
	float Diff;
	KMeansTriple props;
	int m,j,i,temp;

	cvSplit(frame,this->planeR,this->planeG,this->planeB,0);
	cvCalcHist(&this->planeR,this->histR,0,NULL);
    cvCalcHist(&this->planeG,this->histG,0,NULL);
    cvCalcHist(&this->planeB,this->histB,0,NULL);
    
	for(i=0;i<this->numOfBins;i++)
	{ 
     this->imagehist[i]= cvQueryHistValue_1D(this->histR,i);     
	}

	for(temp=this->numOfBins,i=0;i<this->numOfBins;i++)
	{ 
     this->imagehist[i+temp]= cvQueryHistValue_1D(this->histG,i);     
	}

	for(temp+=this->numOfBins,i=0;i<this->numOfBins;i++)
	{ 
     this->imagehist[i+temp]= cvQueryHistValue_1D(this->histB,i);     
	}

	for(props.classID=-1,props.Diff=10000,m=0;m<this->numOfCores;m++)
	{
		for(Diff=0,j=0;j<this->componentLength;j++)	   
		{
		   Diff+=(float) fabs(this->imagehist[j]-this->cores[m][j]);
		}
                
		if(props.Diff>Diff)
		{
			props.Diff=Diff;
			props.classID=m;
		}
	}	

	props.Id=0;
	return props;
}
Beispiel #4
0
IplImage* drawHistogram(CvHistogram* hist)
{
	// Scale
	int scaleX = 2;
	int scaleY = 2;


	float histMax = 0;

	cvGetMinMaxHistValue(hist, 0, &histMax, 0, 0);

	// create blank image
	IplImage* imgHist = cvCreateImage(cvSize(256*scaleX, 64*scaleY), 8 ,1);
	cvZero(imgHist);


	// iterate thro' bins and render out graphics...
	int i=0;
	for(i=0;i<255;i++)
	    {
	        float histValue = cvQueryHistValue_1D(hist, i);
	        float nextValue = cvQueryHistValue_1D(hist, i+1);

	        CvPoint pt1 = cvPoint(i*scaleX, 64*scaleY);
	        CvPoint pt2 = cvPoint(i*scaleX+scaleX, 64*scaleY);
	        CvPoint pt3 = cvPoint(i*scaleX+scaleX, (64-nextValue*64/histMax)*scaleY);
	        CvPoint pt4 = cvPoint(i*scaleX, (64-histValue*64/histMax)*scaleY);

	        int numPts = 5;
	        CvPoint pts[] = {pt1, pt2, pt3, pt4, pt1};

	        cvFillConvexPoly(imgHist, pts, numPts, cvScalar(255,0,0,0),8,0);
	    }






	return imgHist;


}
Beispiel #5
0
// If not ready , it initializes the cores
// else it updates the nearest core to frame and updates the
// number of updates for this particular core
void KMeans::updateCore(IplImage *frame,IplImage *mask)
{	
	int i;

	if(!this->numOfSamples) return;

	if(this->index==0)
	{
		this->planeR = cvCreateImage(cvGetSize(frame),IPL_DEPTH_8U,1);
		this->planeG = cvCreateImage(cvGetSize(frame),IPL_DEPTH_8U,1);
		this->planeB = cvCreateImage(cvGetSize(frame),IPL_DEPTH_8U,1);
	}
	
	cvSplit(frame,this->planeR,this->planeG,this->planeB,0);

	cvCalcHist(&this->planeR,this->histR,0,mask);
	cvCalcHist(&this->planeG,this->histG,0,mask);
	cvCalcHist(&this->planeB,this->histB,0,mask);

	cvNormalizeHist(this->histR,1.0);
	cvNormalizeHist(this->histG,1.0);
	cvNormalizeHist(this->histB,1.0);
	
	float *runner=this->candyset[this->index++];
	
	for(i=0;i<this->numOfBins;i++)
	{ 
		*runner++=cvQueryHistValue_1D(this->histR,i);
	}

	for(i=0;i<this->numOfBins;i++)
	{ 
     *runner++=cvQueryHistValue_1D(this->histG,i);
	}

	for(i=0;i<this->numOfBins;i++)
	{ 
     *runner++=cvQueryHistValue_1D(this->histB,i);
	}
}
Beispiel #6
0
double caculateCurrentEntropy(CvHistogram * Histogram1, int cur_threshold, entropy_state state)
{
	int start, end;
	if (state == back)	{
		start = 0; end = cur_threshold;
	}
	else	{
		start = cur_threshold; end = 256;
	}
	int  total = 0;
	for (int i = start; i < end; i++)	{
		total += (int)cvQueryHistValue_1D(Histogram1, i);
	}
	double cur_entropy = 0.0;
	for (int i = start; i < end; i++){
		if ((int)cvQueryHistValue_1D(Histogram1, i) == 0)
			continue;
		double percentage = cvQueryHistValue_1D(Histogram1, i) / total;
		cur_entropy += -percentage*logf(percentage);
	}
	return cur_entropy;
}
Beispiel #7
0
void mvDumpHistogram (IplImage* img, const char* file_name, char delimiter) {
    FILE* fp = fopen (file_name, "w");
    if (fp == NULL)
        return;    

    const int step_size = 5;
    const int nbins = 255/step_size;

    int size[] = {nbins};
    float range[] = {0, 255};
    float* ranges[] = {range};

    IplImage* channel1 = cvCreateImage (cvGetSize(img), IPL_DEPTH_8U, 1);
    IplImage* channel2 = cvCreateImage (cvGetSize(img), IPL_DEPTH_8U, 1);
    IplImage* channel3 = cvCreateImage (cvGetSize(img), IPL_DEPTH_8U, 1);
    
    // Split image onto the color planes.
    cvSplit(img, channel1, channel2, channel3, NULL);
    IplImage* planes[] = {channel1, channel2, channel3};

    // here we create 3 1-dimensional histograms. Each hist only looks at one of the 3 colors of RGB
    for (int i = 0; i < 3; i++) {
        CvHistogram* hist = cvCreateHist (1, size, CV_HIST_ARRAY, ranges, 1);
        IplImage* curr_plane[] = {planes[i]};
        cvCalcHist (curr_plane, hist, 0, NULL);
        cvNormalizeHist (hist, 10000);

        fprintf (fp, "\nChannel %d Histogram\nRange%cBin #%cCount\n", i+1,delimiter,delimiter);

        // print histogram
        for (int j = 0; j < nbins; j++) {
            int binval = cvQueryHistValue_1D(hist, j);
            fprintf (fp, "%d-%d%c%d%c%d\n", j*step_size,(j+1)*step_size,delimiter,j+1,delimiter,binval);
        }
    }

    cvReleaseImage (&channel1);
    cvReleaseImage (&channel2);
    cvReleaseImage (&channel3);
    fclose (fp);
    printf ("Dumped histogram to %s\n", file_name);
}
void dibuixarHistograma(float max_value)
{
    float value;
    int normalized;
    imgHistogram = cvCreateImage(cvSize(bins*2, 125),8,1);
    cvRectangle(imgHistogram, cvPoint(0,0), cvPoint(bins*2,125), CV_RGB(255,255,255),-1);
    for(int i=0; i < bins; i++)
    {
        value = cvQueryHistValue_1D( hist, i);
        normalized = cvRound(value*100/max_value);
        cvLine(imgHistogram,cvPoint(i*2,100), cvPoint(i*2,100-normalized), CV_RGB(0,0,0));
    }
    CvFont font;
    cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX, 0.4, 0.4, 0, 0.1, CV_AA);
    cvPutText(imgHistogram, "0", cvPoint(5, 120), &font, cvScalar(0, 0, 0, 0));
    cvPutText(imgHistogram, "50", cvPoint(100-10, 120), &font, cvScalar(0, 0, 0, 0));
    cvPutText(imgHistogram, "100", cvPoint(200-15, 120), &font, cvScalar(0, 0, 0, 0));
    cvPutText(imgHistogram, "150", cvPoint(300-15, 120), &font, cvScalar(0, 0, 0, 0));
    cvPutText(imgHistogram, "200", cvPoint(400-15, 120), &font, cvScalar(0, 0, 0, 0));
    cvPutText(imgHistogram, "256", cvPoint(250*2-15, 120), &font, cvScalar(0, 0, 0, 0));
}
Beispiel #9
0
int main(int argc, char *argv[])
{
    // Variable to store the keyboard input
    char d;

    // Initialize flags to false. These flags are used for keyboard input (keys q, r, g and b)
    bool Q = false;
    bool R = false;
    bool G = false;
    bool B = false;

    // Set the capture device. Please change the integer value "0" to appropriate value for the capture device.
    CvCapture* capture = cvCaptureFromCAM(0);

    // Allocate memory for all images
    IplImage *src_img;
    IplImage *histogram;
    IplImage *disp_img;
    IplImage *gray_img;
    IplImage *red_img, *red_histogram;
    IplImage *green_img, *green_histogram;
    IplImage *blue_img, *blue_histogram;

    // Initialize historgrams
    int hist_size = 256;
    float range[] = {0,256};
    float *ranges[] = {range};

    /* cvCreateHist function is used to create the histograms. Following is the explanation of the various arguments of the function
    1. First argument: Defines how many dimensions the histogram will have. To keep things simple this tutorial only uses one dimensional histograms.
    2. Second argument: Defines the size of the dimensions. If we were using higher dimensional histograms we would have to pass an array of sizes, one for each dimension, but we are only using one dimension so the array we pass only has one value in it. We choose to make the size of the dimension 256 because the depth of the images we are working with is 8 bit, meaning that we will get one bin for each intensity level. We could have chosen to have less bins but the histogram would have less resolution. We could have chosen more bins but we would not show any more information.
    3. Third argument: Tells OpenCV how to store the data in the histogram. There are two options for this: CV_HIST_ARRAY and CV_HIST_SPARSE. The second option is useful for storing multidimensional histograms that will have most of their bins with counts of zero. Since we are using a one dimensional histogram, we don’t expect sparse data so we choose the first option.
    4. Fourth argument: Used to specify the range of values for each dimension.  Each range is stored as an array of two values, the minimum and maximum value for that dimension. Again we are using one dimension so it looks a bit redundant to make an array of arrays, but only with one array. We have to do this though, because this fourth argument expects an array to 2 value arrays. It is important to know how OpenCV creates the bins based on the range values and the histogram size. OpenCV will take the value supplied in ranges and break it into as many sub intervals as defined in hist_size.
    5. Fifth argument: Defines if the sub intervals are to be split uniformly or not. For this case we definitely want each bin to be the same width as the others so we choose this argument to be 1.
    */
    CvHistogram* hist_red = cvCreateHist(1, &hist_size, CV_HIST_ARRAY, ranges, 1);
    CvHistogram* hist_blue = cvCreateHist(1, &hist_size, CV_HIST_ARRAY, ranges, 1);
    CvHistogram* hist_green = cvCreateHist(1, &hist_size, CV_HIST_ARRAY, ranges, 1);
    double max_value = 0;
    double max_value_red = 0;
    double max_value_green = 0;
    double max_value_blue = 0;
    double find_max = 0;

    // Create the windows
    // "mainWin"  shows the actual captured image
    cvNamedWindow("mainWin", CV_WINDOW_AUTOSIZE);
    cvMoveWindow("mainWin", 5, 5);
    // "histogramWin" shows the histogram
    cvNamedWindow("histogramWin", CV_WINDOW_AUTOSIZE);
    cvMoveWindow("histogramWin", 435, 5);

    // Print instructions for keyboard input
    printf("RGB Histogram\n\n");
    printf("To toggle red channel ON/OFF press: 'r'\n");
    printf("To toggle green channel ON/OFF press: 'g'\n");
    printf("To toggle blue channel ON/OFF press: 'b'\n");
    printf("To quit press: 'q'\n");

    // Do the following inside while loop forever
    while(1)
    {
        // Clear all max values to 0
        max_value = 0; max_value_red = 0; max_value_green = 0; max_value_blue = 0;

        // Load a bmp image with the histogram axis. Instead of having OpenCV draw the axis, the axis is drawn in paint and then loaded as an image.
        // You can download the picture here: http://uowteaminvincible.files.wordpress.com/2010/02/histogram_scale.png
        // Be sure to change the path below to wherever you choose to save the image.  Also use \\ instead of \ to separate directories.
        histogram = cvLoadImage( "histogram_scale.png" );

        // Initialize three images that will show each histogram
        red_histogram = cvCreateImage( cvGetSize(histogram), IPL_DEPTH_8U, 3 );
        green_histogram = cvCreateImage( cvGetSize(histogram), IPL_DEPTH_8U, 3 );
        blue_histogram = cvCreateImage( cvGetSize(histogram), IPL_DEPTH_8U, 3 );

        // Get the source frame by querying the capture and resize it for display
        src_img=cvQueryFrame(capture);
        disp_img = cvCreateImage(cvSize((src_img->width)/1.6,(src_img->height)/1.6),IPL_DEPTH_8U,3);
        cvResize(src_img,disp_img,CV_INTER_LINEAR);

        // Create 3 single channel images to store each channels data and split the source image into the RGB channels.
        /* Note that each channel is given an image with the same size (width and height) as the source. The depth is 8 bits and these new images have only one channel (since they are storing only one channel). The function cvCvtPixToPlane actually separates the source into its three channels and stores them in the images we just created.*/
        blue_img = cvCreateImage( cvGetSize(src_img), IPL_DEPTH_8U, 1 );
        green_img = cvCreateImage( cvGetSize(src_img), IPL_DEPTH_8U, 1 );
        red_img = cvCreateImage( cvGetSize(src_img), IPL_DEPTH_8U, 1 );
        cvCvtPixToPlane( src_img, blue_img, green_img, red_img, 0 );

        // Calculate a histogram for each channel.
        /*The first argument takes the image we would like to calculate the histogram for. Note that cvCalcHist can only take a one channel image. The next argument says which histogram will be populated. The third argument turns on or off accumulator mode. Since we want the histogram to update for each frame we want to clear the contents before adding new ones and the accumulator mode should be off. The final parameter is a mask that can tell cvCalcHist to unly calculate a certain part of the image. By setting the mask null we calculate for the whole image.*/
        cvCalcHist( &red_img, hist_red, 0, NULL );
        cvCalcHist( &blue_img, hist_blue, 0, NULL );
        cvCalcHist( &green_img, hist_green, 0, NULL );

        // Search through the histograms for their maximum value and store it.
        /* The code for finding the maximum value for the red channel is shown above. The other two channels are very similar and shown in the source code. It is done with a simple for loop that checks every value in each bin. The function used to get the values out of the histogram is cvQueryHistValue_1D. This function is made for getting values out of a one dimensional histogram. Its arguments are the histogram you want to look into, and the bin number you want to see. The reason we need to find this max value is that we will scale the y-axis of the histogram so that it fits on the screen. We do this by dividing each bin value by the max value (this is done in the next step).*/
        for( int i = 0; i < hist_size; i++ )
        {
            find_max = cvQueryHistValue_1D(hist_red,i);
            if (find_max > max_value_red)
            {
                max_value_red = find_max;
            }
        }
        for( int i = 0; i < hist_size; i++ )
        {
            find_max = cvQueryHistValue_1D(hist_green,i);
            if (find_max > max_value_green)
            {
                max_value_green = find_max;
            }
        }
        for( int i = 0; i < hist_size; i++ )
        {
            find_max = cvQueryHistValue_1D(hist_blue,i);
            if (find_max > max_value_blue)
            {
                max_value_blue = find_max;
            }
        }
        // The largest value in all the histograms is found.
        max_value = max(max(max_value_red,max_value_green),max_value_blue);

        // Draw the histogram for each channel, if the flag for that channel is set
        /* First we see an if statement that controls whether or not we draw the histogram. It is based on a flag that is set in the next step by user input. This allows the user to select which channel or combination of channels that they want to see. The next step is the scaling. The function cvScale is used. Its first argument is the source to be scaled and the second is the destination for result. Here we used the same place for source and destination meaning that the bins are scaled and then stored back in the same place. The last argument is the scale factor. A factor of 438/max_value was used because the highest bar that we want to draw is 438 pixels high (so it does not go out of the bounds of the picture we used for the axis). Inside the for loop we see a complicated line of code that draws all the rectangles. The function cvRectangle is used for this. It requires that we pass it which image to draw on, two points to define the rectangles, the colour and line thickness. We specify line thickness as -1 which means a filled rectangle. The last function used is cvAdd which is used to simplify drawind the multiple histograms with overlap. By adding colours on top of each other no extar code is required to deal with the overlap.*/
        if (R)
        {
            cvScale( hist_red->bins, hist_red->bins, 438/max_value);
            for( int i= 0; i < hist_size; i++ )
            {
                cvRectangle( red_histogram, cvPoint(i*3+ 15, 448),cvPoint(i*3+16, 448 - cvRound(cvQueryHistValue_1D(hist_red,i))),cvScalar(0x00,0x00,0xff,0), -1);
            }
            cvAdd(histogram,red_histogram,histogram,0);
        }
        if (G)
        {
            cvScale( hist_green->bins, hist_green->bins, 438/max_value);
            for( int i= 0; i < hist_size; i++ )
            {
                cvRectangle( green_histogram, cvPoint(i*3+ 15, 448),cvPoint(i*3+16, 448 - cvRound(cvQueryHistValue_1D(hist_green,i))),cvScalar(0x00,0xff,0x00,0), -1);
            }
            cvAdd(histogram,green_histogram,histogram,0);
        }
        if (B)
        {
            cvScale( hist_blue->bins, hist_blue->bins, 438/max_value);
            for( int i= 0; i < hist_size; i++ )
            {
                cvRectangle( blue_histogram, cvPoint(i*3+ 15, 448),cvPoint(i*3+16, 448 - cvRound(cvQueryHistValue_1D(hist_blue,i))),cvScalar(0xff,0x00,0x00,0), -1);
            }
            cvAdd(histogram,blue_histogram,histogram,0);
        }

        // Show the images in the windows
        cvShowImage("mainWin", disp_img);
        cvShowImage("histogramWin", histogram);

        // Set flags
        d=cvWaitKey(15);
        /* A simple case statement takes the input from the keyboard and sets the flags accordingly. The R, G and B flags are XOR’ed with 1 to change state each time r, g, or b is pressed. This makes r g and b into toggle switches.*/
        switch (d)
        {
            case 'r':   R = R^1;    break;
            case 'g':   G = G^1;    break;
            case 'b':   B = B^1;    break;
            case 'q':   Q = true;   break;
            default:    break;
        }
        if(Q)break;     //quit program

        // Release the images that we created
        cvReleaseImage(&disp_img );
        cvReleaseImage(&red_img );
        cvReleaseImage(&green_img );
        cvReleaseImage(&blue_img );
        cvReleaseImage(&red_histogram );
        cvReleaseImage(&green_histogram );
        cvReleaseImage(&blue_histogram );
        cvReleaseImage(&histogram );
    }
    return 0;
}
Beispiel #10
0
//命令模式: 程序名 文件名1 文件名2.。。。。。
int main( int argc, char** argv ) 
{
	IplImage* frame;

	if(argc<2)
		return 0;

	frame= cvLoadImage(argv[1],1);

	//获取直方图
	IplImage* r_plane = cvCreateImage(cvGetSize(frame),8,1);
	IplImage* g_plane = cvCreateImage(cvGetSize(frame),8,1);
	IplImage* b_plane = cvCreateImage(cvGetSize(frame),8,1);
	IplImage* gray_plane = cvCreateImage(cvGetSize(frame),8,1);

	cvCvtPixToPlane(frame,b_plane,g_plane,r_plane,0);
	cvCvtColor(frame,gray_plane,CV_BGR2GRAY);

	//直方图均衡化
	//cvEqualizeHist(gray_plane,gray_plane);

	int hist_size=256;
	float range[] = {0,255};
	float* ranges[]={range};

	CvHistogram* r_hist = cvCreateHist(1,&hist_size,CV_HIST_ARRAY,ranges,1);
	CvHistogram* g_hist = cvCreateHist(1,&hist_size,CV_HIST_ARRAY,ranges,1);
	CvHistogram* b_hist = cvCreateHist(1,&hist_size,CV_HIST_ARRAY,ranges,1);
	CvHistogram* gray_hist = cvCreateHist(1,&hist_size,CV_HIST_ARRAY,ranges,1);

	//CvRect rect={0,0,1,frame->height};
	//cvSetImageROI(b_plane,rect);

	cvCalcHist( &r_plane, r_hist, 0, 0 );
	cvCalcHist( &g_plane, g_hist, 0, 0 );
	cvCalcHist( &b_plane, b_hist, 0, 0 );
	cvCalcHist( &gray_plane, gray_hist, 0, 0 );

	//归一成1.0为最高
	cvNormalizeHist(gray_hist,1.0);

#if 1
	//替代的功能相同的直方图均衡化算法
	float F[256];
	unsigned char G[256];

	for (int i=0;i<hist_size;i++)
	{
		float s= cvQueryHistValue_1D(gray_hist,i) *255;
		if(0==i)
			F[i]=s;
		else
			F[i]=F[i-1]+s;
	}
	
	for (int i=0;i<hist_size;i++)
		G[i]=(unsigned char)(int)F[i];

	CvMat lookup=cvMat(1,256,CV_8U,G);

	cvLUT(gray_plane,gray_plane,&lookup);

	cvCalcHist( &gray_plane, gray_hist, 0, 0 );

	//归一成1.0为最高
	cvNormalizeHist(gray_hist,1.0);
#endif


	//获取直方图的最大值和最大值处在的位置
	float max_value = 0;
	int max_idx=0;
	cvGetMinMaxHistValue(gray_hist, NULL, &max_value, 0, &max_idx);

	double k=0;
	for (int i=0;i<hist_size;i++)
	{
		float  bins= cvQueryHistValue_1D(gray_hist,i);
		//	if(i>=179 &&i<=200)
	//	k+=bins;
	//	printf("%d=%f\n",i,bins);
		printf("%d=%f",i,bins);
		for(int j=0;j<(int)(bins/0.0001);j++)
		{
			printf("-");
		}
		printf("\n");

	}
	printf("%f",k);

	cvReleaseHist(&r_hist);
	cvReleaseHist(&g_hist);
	cvReleaseHist(&b_hist);
	cvReleaseHist(&gray_hist);


	cvSaveImage( argv[1], frame );


	cvReleaseImage(&frame);
	return 0;

}
int llindar_gaussian(IplImage* img, CvHistogram* histo)
{
    int i = 0;
    int aux = 0;
    int maxPrimer = 0;
    int idxMaxPrimer = 0;
    int maxSegon = 0;
    int idxMaxSegon = 0;

    /*Obtenció del màxim absolut*/
    while (i < bins)
    {
        aux = cvQueryHistValue_1D( hist, i);
        if( aux > maxPrimer) {
            maxPrimer = aux;
            idxMaxPrimer = i;
        }
        i++;
    }
    /*Obtenció del segon màxim absolut*/
    i=0;
    while (i < bins)
    {
        aux = cvQueryHistValue_1D( hist, i);
        if((pow((i-idxMaxPrimer),2) * aux) > maxSegon){
            maxSegon = pow((i-idxMaxPrimer),2)*aux;
            idxMaxSegon = i;
        }
        i++;
    }
    /*Suavització del histograma*/
    i=0;
    int* histValors = new int[256];
    int suavizat = 3;

    while (i < bins)
    {
        int suma = 0;
        for(int k = i-(suavizat-1/2); k <= i+(suavizat-1/2); k++)
        {
            if(k>=0 && k < bins)
            {
                suma+= cvQueryHistValue_1D( hist, k);
            }
            histValors[i] = suma/suavizat;
        }
        i++;
    }

    dibuixarHistogramaSuavizat(maxPrimer, histValors);

    /*En aquest cas, l'objecte és més fosc que el fons*/
    /*Càlcul del llindar: es busca una pendent positiva superior a 200*/
    int j;
    int finestra = 10;
    boolean trobat = false;
    for(j=idxMaxSegon+finestra; j<idxMaxPrimer && !trobat;j++){
        int aux = histValors[j] - histValors[j-finestra];
        if(aux > 200) trobat = true;
    }
    return j - finestra/2;
}
IplImage* getTone(const char *filename)
{
	//实现论文中提到的正常铅笔画应有的直方图
	double p1, p2, p3, p[256];
	double temp = sqrt(2 * CV_PI * 10);
	for (int i = 0; i < 256; i++) {
		p1 = 1 / 9.0 * exp(-(256 - i) / 9.0);
		p2 = (i >= 105 && i <= 225) / (225 - 105.0);
		p3 = exp(-(i - 80)*(i - 80) / (2.0 * 10 * 10)) / temp;
		p[i] = 0.52 * p1 + 0.37 * p2 + 0.11 * p3;
	}
	smooth(p, 256);
	smooth(p, 256);
	double sum = 0;
	for (int i = 0; i < 256; i++) sum += p[i];
	for (int i = 0; i < 256; i++) p[i] /= sum;
	double G[256];
	G[0] = p[0];
	for (int i = 1; i < 256; i++) G[i] = G[i - 1] + p[i];

	//计算原图的直方图
	IplImage *pToneImage = cvLoadImage(filename, CV_LOAD_IMAGE_GRAYSCALE);
	Image img(pToneImage);
	int h = pToneImage->height;
	int w = pToneImage->width;

	CvHistogram *pHis = CreateGrayImageHist(&pToneImage);
	double S[256];
	S[0] = cvQueryHistValue_1D(pHis, 0) / (h*w);
	for (int i = 1; i < 256; i++)
		S[i] = S[i - 1] + cvQueryHistValue_1D(pHis, i) / (h*w);

	//进行直方图匹配
	int index[256];
	for (int i = 0; i < 256; i++) {
		int k = 0;
		for (int j = 1; j < 256; j++)
			if (abs(G[k] - S[i]) > abs(G[j] - S[i])) k = j;
		index[i] = k;
	}

	for (int i = 0; i < h; i++)
		for (int j = 0; j < w; j++) img[i][j] = index[img[i][j]];

	//Pencil Texture Rendering
	IplImage *pRender = cvLoadImage("Tonal Texture.png", CV_LOAD_IMAGE_GRAYSCALE);
	Image pR(pRender);
	double **b = new double*[h];
	for (int i = 0; i < h; i++) 
	{
		b[i] = new double[w];
		for (int j = 0; j < w; j++)
		{
			double H = pR[i % pR.getH()][j % pR.getW()] / 256.0;
			double J = img[i][j] / 256.0;
			double bx = (i) ? b[i - 1][j] : 0;
			double by = (j) ? b[i][j - 1] : 0;
			double A = 0.2 * 2 + log(H)*log(H);
			double B = -2*(0.2*(bx + by) + log(H)*log(J));
			b[i][j] = -B / (2*A);
			img[i][j] = pow(H, b[i][j]) * 256;
		}
	}
	return pToneImage;
}
Beispiel #13
0
CvScalar GetSharpness(IplImage* in, IplImage* drawHist=0)
{
	const  short history_size           = 5;
    static short history_index          = 0;
    static short history[5];

    static IplImage* data = 0;
    static IplImage* out = 0;
    static IplImage* out_8bit = 0;

	if( ! out ) {
        out=cvCreateImage(cvSize(in->roi->width,in->roi->height),IPL_DEPTH_16S,1);
		out_8bit=cvCreateImage(cvSize(in->roi->width,in->roi->height),IPL_DEPTH_8U,1);
    }

    // aperture size of 1 corresponds to the correct matrix
    cvLaplace(in, out, 1);

    short maxLap = -32767;
    short* imgData = (short*)out->imageData;
    int i=0;
	double avg=0.0;
    for(i=0;i<(out->imageSize/2);i++)
    {
        if(abs(imgData[i]) > maxLap) maxLap = abs(imgData[i]);
		avg += abs(imgData[i]);
    }
	avg /= out->imageSize;

	history[history_index++] = maxLap;
    history_index = (history_index + 1) % history_size;
    float mean = 0.0;
    for(i=0;i<history_size;i++) {
		mean+=history[i];
	}
    mean /= history_size;

	if(drawHist) {
        cvConvertScale(out,out_8bit);

	    CvHistogram* hist;
	    int hist_size[] = { 256 };
	    float ranges_1[] = { 0, 256 };
	    float* ranges[] = { ranges_1 };
	    hist = cvCreateHist( 1, hist_size, CV_HIST_ARRAY, ranges, 1 );

	    cvCalcHist( &out_8bit, hist, 0, 0 ); // Compute histogram
	    cvNormalizeHist( hist, 20*255 ); // Normalize it

        // populate the visualization
	    float max_value = 0;
	    cvGetMinMaxHistValue( hist, 0, &max_value, 0, 0 );

	    for( int s = 0; s < 256; s++ ){
	    	float bin_val = cvQueryHistValue_1D( hist, s );
			if(bin_val>0.0) {
				cvRectangle( drawHist, cvPoint( s, 100 ),
						cvPoint( s, 100- (bin_val/max_value*100)),
						CV_RGB( 0, 255, 0 ),
						CV_FILLED );
			}
	    }

	    cvReleaseHist(&hist);
    }

	CvScalar r;
	r.val[0] = mean;
    r.val[1] = avg;
	return r;
}
int main()
{

	
	bool salir=FALSE;

	
	

do
{
	IplImage *im;
	char eleccion;
	bool j=TRUE;

	//Panel

	printf("Elija la imagen que quiere cargar\n");
	printf("Imagenes del programa:\n\n"
		   "A=2_bolas\n"
		   "B=3_bolas\n"
		   "C=4_bolas\n"
		   "D=6_bolas\n"
		   "E=bola_azul\n"
		   "F=bola_roja\n"
		   "G=bolas_cortadas\n"
		   "H=bola_amarilla_blanca\n"
		   "I=bola_amarilla_blanca_+intensidad\n"
		   "J=bola_amarilla1\n"
		   "K=bolas_cortadas_+intensidad\n"
		   "L=bolas_juntas\n"
		   "M=cambio_angulo_iluminacion\n"
		   "N=bolas_pegadas_1\n"
		   "O=bolas_pegadas_2\n"
		   "P=bolas_pegadas_3\n"
		   "Q=bolas_pegadas_4\n"
		   "R=bolas_pegadas_4_+intensidad\n"
		   "S=bolas_pegadas_rotas\n"
		   "T=bolas_pegadas_rotas_2\n"
		   

		   );

	printf("X=SALIR\n\n");

while(j==TRUE)
{
	

	
	scanf("%c",&eleccion);
	
	

	switch(eleccion)
	{
	case 'A':{   char NombreImagen[]="2_bolas.jpg"; im=cvLoadImage(NombreImagen, -1); j=FALSE;}
		    break;

	case 'B':  {char NombreImagen[]="3_bolas.jpg"; im=cvLoadImage(NombreImagen, -1);j=FALSE;}
		    break;

	case 'C': { char NombreImagen[]="4_bolas.jpg"; im=cvLoadImage(NombreImagen, -1);j=FALSE;}
		    break;

	case 'D':  { char NombreImagen[]="6_bolas.jpg"; im=cvLoadImage(NombreImagen, -1);j=FALSE;}
		    break;

	case 'E':  { char NombreImagen[]="bola_azul.jpg"; im=cvLoadImage(NombreImagen, -1);j=FALSE;}
		    break;
		   
	case 'F':  {char NombreImagen[]="bola_roja.jpg"; im=cvLoadImage(NombreImagen, -1);j=FALSE;}
		    break;

	case 'G':  {char NombreImagen[]="bolas_cortadas.jpg"; im=cvLoadImage(NombreImagen, -1);j=FALSE;}
		    break;

	case 'H':  {char NombreImagen[]="bola_amarilla_blanca.jpg"; im=cvLoadImage(NombreImagen, -1);j=FALSE;}
		    break;

	case 'I': { char NombreImagen[]="bola_amarilla_blanca_+intensidad.jpg"; im=cvLoadImage(NombreImagen, -1);j=FALSE;}
		    break;

	case 'J': { char NombreImagen[]="bola_amarilla1.jpg"; im=cvLoadImage(NombreImagen, -1);j=FALSE;}
		    break;

	case 'K':  { char NombreImagen[]="bolas_cortadas_+intensidad.jpg"; im=cvLoadImage(NombreImagen, -1);j=FALSE;}
		    break;

	case 'L': { char NombreImagen[]="bolas_juntas.jpg"; im=cvLoadImage(NombreImagen, -1);j=FALSE;}
		    break;

	case 'M':  {char NombreImagen[]="cambio_angulo_iluminacion.jpg"; im=cvLoadImage(NombreImagen, -1);j=FALSE;}
		    break;

	case 'N':  {char NombreImagen[]="bolas_pegadas_1.jpg"; im=cvLoadImage(NombreImagen, -1);j=FALSE;}
		    break;

	case 'O':  {char NombreImagen[]="bolas_pegadas_2.jpg"; im=cvLoadImage(NombreImagen, -1);j=FALSE;}
		    break;

	case 'P':  {char NombreImagen[]="bolas_pegadas_3.jpg"; im=cvLoadImage(NombreImagen, -1);j=FALSE;}
		    break;

	case 'Q':  {char NombreImagen[]="bolas_pegadas_4.jpg"; im=cvLoadImage(NombreImagen, -1);j=FALSE;}
		    break;

	case 'R':  {char NombreImagen[]="bolas_pegadas_4_+intensidad.jpg"; im=cvLoadImage(NombreImagen, -1);j=FALSE;}
		    break;

	case 'S':  {char NombreImagen[]="bolas_pegadas_rotas.jpg"; im=cvLoadImage(NombreImagen, -1);j=FALSE;}
		    break;

	case 'T':  {char NombreImagen[]="bolas_pegadas_rotas_2.jpg"; im=cvLoadImage(NombreImagen, -1);j=FALSE;}
		    break;

	case 'X':  {salir=TRUE; return 0;}
		    break;


	default:{ printf("Eleccion incorrecta, vuelva a elegir una opcion\n"); j=TRUE; }
	}

}
		













	
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
	
//OBTENER UNA IMAGEN BINARIA SÓLO CON BOLAS AZULES Y OTRA SÓLO CON BOLAS ROJAS 

	
	
	IplImage *Imagen_RGB;
	
    
	
	IplImage *Imagen_umbr;
	IplImage *Imagen_umbr_2;
	


	CvSize Dimensiones;

	//umbrales de la imagenS y la imagenH. En esta parte no utilizo la función MinMax porque me sale mejor poniendo  unos umbrales fijos
	int umbral1=150;
	int umbral2=100;
	
	

	

	//pasamos de BGR a RGB

	Dimensiones= cvGetSize(im);

	Imagen_RGB=cvCreateImage(Dimensiones,IPL_DEPTH_8U,3);
	cvCvtColor(im,Imagen_RGB,CV_BGR2RGB);



	
IplImage *ImagenHSV;
IplImage *ImagenH,*ImagenS,*ImagenV;




//pasamos de RGB a HSV

ImagenHSV=cvCreateImage(Dimensiones,IPL_DEPTH_8U,3);

cvCvtColor(Imagen_RGB,ImagenHSV,CV_RGB2HSV);



//Extraemos de la imagen HSV sus tres componentes: H, S y V


ImagenH=cvCreateImage(Dimensiones,IPL_DEPTH_8U,1);
ImagenS=cvCreateImage(Dimensiones,IPL_DEPTH_8U,1);
ImagenV=cvCreateImage(Dimensiones,IPL_DEPTH_8U,1);
cvSplit(ImagenHSV,ImagenH,ImagenS,ImagenV,0);

//imagenes binarias para umbralizar Sy H

Imagen_umbr=cvCreateImage(Dimensiones,IPL_DEPTH_8U,1);
Imagen_umbr_2=cvCreateImage(Dimensiones,IPL_DEPTH_8U,1);

//umbralizacion.
cvThreshold(ImagenS,Imagen_umbr,umbral1,255,CV_THRESH_BINARY);

cvThreshold(ImagenH,Imagen_umbr_2,umbral2,255,CV_THRESH_BINARY_INV);



//Descompongo la imagen en R,G y B

IplImage *ImagenR=cvCreateImage(Dimensiones,IPL_DEPTH_8U,1);
IplImage *ImagenG=cvCreateImage(Dimensiones,IPL_DEPTH_8U,1);
IplImage *ImagenB=cvCreateImage(Dimensiones,IPL_DEPTH_8U,1);

cvSplit(Imagen_RGB,ImagenR,ImagenG,ImagenB,0);




//A partir de aquí hago una serie de transformaciones morfológicas para separar en imágenes binarias las bolas azules de las rojas.


    //creo elemento estructurante

	 IplConvKernel* element = 0;
     const int element_shape =CV_SHAPE_ELLIPSE;
	 int pos=1;
  
     element= cvCreateStructuringElementEx(pos*2+1,pos*2+1,pos,pos, element_shape,0);
	
	


    IplImage * temp= cvCreateImage(cvGetSize(Imagen_umbr),IPL_DEPTH_8U,1);
    IplImage *temp2=cvCreateImage(cvGetSize(Imagen_umbr),IPL_DEPTH_8U,1);
	IplImage *resta=cvCreateImage(cvGetSize(Imagen_umbr),IPL_DEPTH_8U,1);
	
	
	//con esto obtengo todas las bolas binarizadas
	
	cvMorphologyEx(Imagen_umbr,temp,temp, NULL,CV_MOP_TOPHAT,2);     //tophat. Me detecta sólo las sombras de las bolas. Mi iluminación iene de arriba.
	//cvMorphologyEx(Imagen_umbr,temp,temp, NULL,CV_MOP_BLACKHAT,2); Esto podria aplicarlo si las sombras se crearan en el lado contrario
	cvAbsDiff (Imagen_umbr, temp ,temp); //resto  la original - el tophat
	cvMorphologyEx(temp,temp,temp, NULL,CV_MOP_CLOSE,6); //aplico el cierre




	//Con esto obtengo las bolas azules binarizadas

	cvMorphologyEx(Imagen_umbr_2,temp2,temp2, NULL,CV_MOP_TOPHAT,1);     //tophat
	//cvMorphologyEx(Imagen_umbr,temp,temp, NULL,CV_MOP_BLACKHAT,2);
	cvAbsDiff (Imagen_umbr_2, temp2 ,temp2); //resto  la original - el tophat
	cvMorphologyEx(temp2,temp2,temp2, NULL,CV_MOP_CLOSE,6); //aplico el cierre

	//Dilato y erosiono el mismo número de veces, para que las bolas me queden mas o menos del mismo tamaño. Además lo hago muchas veces(15), para eliminar los
	//máximos defectos posibles debido a sombras y cambios y contrastes debido a la iluminación
	cvDilate(temp2,temp2,element,15);

	cvErode(temp2,temp2,element,15);


	cvAbsDiff (temp2, temp ,resta); // Resto la imagen de todas las bolas -la imagen de las bolas azules, dilato mcuhas veces y erosiono muchas veces,
	//y finalmente solo me quedan las rojas
	cvDilate(resta,resta,element,15);//dilato

	cvErode(resta,resta,element,15);//erosiono

    //Puede que algun contorno no deseado aún permanezca en la imagen binaria. Como aplico las mismas transformaciones morfológicas a las dos imágenes binarias 
	//tendré el mismo defecto en las dos imagenes, así que  obtengo una imagen sólo los defectos, y después resto los defectos a las dos imágenes.


IplImage * temp3= cvCreateImage(cvGetSize(Imagen_umbr),IPL_DEPTH_8U,1);
IplImage * temp4= cvCreateImage(cvGetSize(Imagen_umbr),IPL_DEPTH_8U,1);
IplImage * Im_defectos_comunes= cvCreateImage(cvGetSize(Imagen_umbr),IPL_DEPTH_8U,1);
IplImage * Im_bolas_azules= cvCreateImage(cvGetSize(Imagen_umbr),IPL_DEPTH_8U,1);
IplImage * Im_bolas_rojas= cvCreateImage(cvGetSize(Imagen_umbr),IPL_DEPTH_8U,1);


cvThreshold(temp2,temp3,umbral2,255,CV_THRESH_BINARY_INV);//invierto las bolas rojas

cvThreshold(resta,temp4,umbral2,255,CV_THRESH_BINARY_INV);//invierto las bolas azules

cvAnd(temp3,temp4,Im_defectos_comunes,NULL);//multiplico las dos imagenes, la imagen que obtengo solo aparecen los defectos comunes

cvAbsDiff (temp2,Im_defectos_comunes,Im_bolas_azules);//resto los defectos a las bolas azules

cvAbsDiff (resta, Im_defectos_comunes ,Im_bolas_rojas);//resto los defectos a las bolas rojas

//Ya tengo una imagen binaria sólo con las bolas azules y otra sólo con las rojas.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------



//CALCULAR HISTOGRAMA DE LA IMAGEN G






//Nueva imagen para dibujar el histograma
IplImage *histImage;
//Variables para el histograma
int hist_size=256;
int NivelGris;
float NumPixels;
//Estructura histograma para guardar la informacion
CvHistogram *hist;




//Nueva imagen para dibujar el histograma
histImage = cvCreateImage(cvSize(256,256), 8, 1);
//Estructura histograma para guardar la informacion
hist = cvCreateHist(1, &hist_size, CV_HIST_ARRAY,NULL, 1);
//calcular el histograma. Lo hago con la imagenG, ya que hay más contraste que en la imagen en escala de grises, pero también funcionaria con la imagen de escala de grises
cvCalcHist(&ImagenG,hist,0,NULL);
cvSetZero(histImage);

long Histograma[256];

//dibujo el histograma
for(NivelGris=0;NivelGris<hist_size;++NivelGris)
{
NumPixels=cvQueryHistValue_1D(hist,NivelGris)/15;
cvLine(histImage,cvPoint(NivelGris,256),cvPoint(NivelGris,256-NumPixels),CV_RGB(255,255,255),1,8,0);

Histograma[NivelGris]=NumPixels;//meto en un array el numero de pixels para cada nivel de gris
}

cvReleaseHist(&hist);
cvSaveImage("Histograma.jpg",histImage,0);
      
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


//UMBRALIZACIÓN DE LA IMAGEN G


IplImage *imagen_bin;
CvMemStorage *Memoria;
CvSeq *Contorno, *Primer_Contorno;
int Nc;
//imagen=cvLoadImage("herramientas.tif",CV_LOAD_IMAGE_GRAYSCALE);
imagen_bin=cvCreateImage(cvGetSize(ImagenG),8,1);
//imagen_color=cvCreateImage(cvGetSize(ImagenG),8,3);

//umbralizar la ImagenG
int umbral;


umbral=MinMax(Histograma);

//Para algunas imagenes, debido a que tienen mas iluminacion o se introducen otros objetos como la mano, en el histograma las gausianas se juntan mucho o solo aparece
//una. En este caso la función MinMAx() calcula  un umbral muy alto y hace que no se detecten los contornos de algunas bolas, asi que establezco un umbral máximo

if(umbral>100)
{
	umbral=100;
}


cvLine(histImage,cvPoint(umbral,256),cvPoint(umbral,0),CV_RGB(255,255,255),1,8,0);//uDibujo el umbral en el histograma


cvThreshold(ImagenG,imagen_bin,umbral,255,CV_THRESH_BINARY_INV);//Binarizo la imagen G

cvMorphologyEx(imagen_bin,imagen_bin,imagen_bin, NULL,CV_MOP_CLOSE,6);//Alplico cierre para eliminar los cambios de contraste en el interior de las bolas 
//debido al reflejo al reflejo de la luz

	
 



//---------------------------------------------------------------------------------------------------------------------------------------------------------------------


// CÁLCULO DE CONTORNOS, ÁREAS, PERÍMETROS, CAJAS Y CENTROS DE CAJA EN LA IMAGEN G.

 IplConvKernel* element_2 = 0;
     const int element_shape_2 =CV_SHAPE_ELLIPSE;
	 int pos_2=1;
  
     element_2= cvCreateStructuringElementEx(pos_2*2+1,pos_2*2+1,pos_2,pos_2, element_shape_2,0);


Memoria=cvCreateMemStorage();
bool k=FALSE;
int n=0;
bool pelotas_juntas=FALSE;
int i;
double *perimetro;
double *area;
CvBox2D *BoundBox;

 CvPoint *centro;

int bolas_rotas_azules=0;
int bolas_rotas_rojas=0;

CvScalar s3;






     Nc=cvFindContours(imagen_bin,Memoria,&Primer_Contorno,sizeof(CvContour),CV_RETR_EXTERNAL);
   


     perimetro=(double*)malloc(Nc*sizeof(double));
     area=(double*)malloc(Nc*sizeof(double));
     BoundBox=(CvBox2D*)malloc(Nc*sizeof(CvBox2D));
	 centro=(CvPoint*)malloc(Nc*sizeof(CvPoint));
	
	
     for(i=0,Contorno=Primer_Contorno;Contorno!=NULL;Contorno=Contorno->h_next,++i)
     {
	      area[i]=cvContourArea(Contorno,CV_WHOLE_SEQ);
	      perimetro[i]=cvArcLength(Contorno,CV_WHOLE_SEQ,1);
	      BoundBox[i]=cvMinAreaRect2(Contorno,NULL);
		  

     }

	  for(i=0;i<Nc;++i)
      {

		  centro[i] = cvPoint( BoundBox[i].center.x,BoundBox[i].center.y);
      }

//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------	  

//DETECTAR BOLAS ROTAS	  
	  
	  
	  
	  
IplImage * inv_bolas_azules, *inv_bolas_rojas;
CvMemStorage *storage_2;
CvMemStorage *storage_3;
CvSeq *Contorno_2, *Primer_Contorno_2;
CvSeq *Contorno_3, *Primer_Contorno_3;

int Nc_2;
int Nc_3;
double *area_2;
double *area_3;
CvBox2D *BoundBox_2;
CvBox2D *BoundBox_3;
CvPoint *centro_2;
CvPoint *centro_3;



inv_bolas_azules=cvCreateImage(cvGetSize(Im_bolas_azules),8,1);

inv_bolas_rojas=cvCreateImage(cvGetSize(Im_bolas_rojas),8,1);

cvThreshold(Im_bolas_azules,inv_bolas_azules,128,255,CV_THRESH_BINARY_INV);
cvThreshold(Im_bolas_rojas,inv_bolas_rojas,128,255,CV_THRESH_BINARY_INV);

storage_2=cvCreateMemStorage();
storage_3=cvCreateMemStorage();


//detecto las bolas rotas azules
Nc_2=cvFindContours(inv_bolas_azules,storage_2,&Primer_Contorno_2,sizeof(CvContour),CV_RETR_EXTERNAL); //Encuentro cotornos en la imagen binaria donde sólo aparecen 
                                                                                                       //las bolas azules



     
     area_2=(double*)malloc(Nc_2*sizeof(double));//tamaño del vector area
     
     BoundBox_2=(CvBox2D*)malloc(Nc_2*sizeof(CvBox2D));//tamaño  del vector BoundBox_2
	 
	 centro_2=(CvPoint*)malloc(Nc_2*sizeof(CvPoint));//tamaño del vector centro_2
	 
	

     for(i=0,Contorno_2=Primer_Contorno_2;Contorno_2!=NULL;Contorno_2=Contorno_2->h_next,++i)
     {
	      area_2[i]=cvContourArea(Contorno_2,CV_WHOLE_SEQ);//Hallo el area de cada contorno
	      
	      
	      BoundBox_2[i]=cvMinAreaRect2(Contorno_2,NULL);//Hallo las caja de cada contorno
		  
		  
		  
	 }

	  for(i=0;i<Nc_2;++i)
      {

		  centro_2[i] = cvPoint( BoundBox[i].center.x,BoundBox[i].center.y);// Hallo el centro de cada contorno
      }

	 
	  
	  
	 
	  
	 //Para cada contorno, si su area es menor que 2500, es que se trata de una bola rota


	  for(i=0;i<Nc_2;++i)
	  {
		  if(area_2[i]<2500)
		  {
			  bolas_rotas_azules++;
			  DibujarBox2D(im,BoundBox_2[i]);
			  printf("Bola  rota azul en:\n x=%d\n y=%d\n",centro[i].y,centro[i].x);
		  }
	  }


	//Detecto las bolas rotas rojas

	// Es el mismo procedimiento que para detectar las bolas rotas azules, pero encontrando contornos en la imagen binaria donde solo aparecen las bolas rojas
	  Nc_3=cvFindContours(inv_bolas_rojas,storage_3,&Primer_Contorno_3,sizeof(CvContour),CV_RETR_EXTERNAL);



     
     area_3=(double*)malloc(Nc_3*sizeof(double));
     
     BoundBox_3=(CvBox2D*)malloc(Nc_3*sizeof(CvBox2D));
	 
	  centro_3=(CvPoint*)malloc(Nc*sizeof(CvPoint));
	 
	 
	

     for(i=0,Contorno_3=Primer_Contorno_3;Contorno_3!=NULL;Contorno_3=Contorno_3->h_next,++i)
     {
	      area_3[i]=cvContourArea(Contorno_3,CV_WHOLE_SEQ);
	      
	      
	      BoundBox_3[i]=cvMinAreaRect2(Contorno_3,NULL);
		  
		  
		  
	 }

	  for(i=0;i<Nc_3;++i)
      {

		  centro_3[i] = cvPoint( BoundBox[i].center.x,BoundBox[i].center.y);
      }
	  
	  
	  
	 
	  for(i=0;i<Nc_3;++i)
	  {
		  if(area_3[i]<2000)
		  {
			  bolas_rotas_rojas++;
			  DibujarBox2D(im,BoundBox_3[i]);
			  printf("Bola  rota roja en:\n x=%d\n y=%d\n",centro[i].y,centro[i].x);
		  }
	  }

	  
	  
	  
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//CASO DE LAS BOLAS JUNTAS

// En el caso de que haya dos o más bolas juntas, el programa encuentra un contorno con el área de todas las bolas que están juntas. Para solucionar este problema
//utilizo el perímetro de los contornos. Elijo un valor umbral para el perímetro en el que me aseguro que se han separado todas las bolas. Así, si existe un perímetro 
//mayor al umbral, erosiono la imagen hasta que todos los perímetros sean menores que ese umbral. 
	 
// Para detectar si hay bolas juntas, compruebo si existe algún controno que tenga el área mayor que el de una bola . 	 
	 for(i=0;i<Nc;++i)
	 {
		 if(area[i]>4000)//si existe el área de un contorno mayor al área de una bola
		 {
			 k=TRUE;
			 pelotas_juntas=TRUE;
		 }

		 
	 }

while(k==TRUE)// Se mete en este bucle si ha encontrado algun área mayor que el de una bola
{

		 k=FALSE;
		 Nc=cvFindContours(imagen_bin,Memoria,&Primer_Contorno,sizeof(CvContour),CV_RETR_EXTERNAL);
  


     perimetro=(double*)malloc(Nc*sizeof(double));
     area=(double*)malloc(Nc*sizeof(double));
     
     BoundBox=(CvBox2D*)malloc(Nc*sizeof(CvBox2D));
	
	 centro=(CvPoint*)malloc(Nc*sizeof(CvPoint));
	
	 

     for(i=0,Contorno=Primer_Contorno;Contorno!=NULL;Contorno=Contorno->h_next,++i)
     {
	      area[i]=cvContourArea(Contorno,CV_WHOLE_SEQ);
	      perimetro[i]=cvArcLength(Contorno,CV_WHOLE_SEQ,1);
	     
	      BoundBox[i]=cvMinAreaRect2(Contorno,NULL);
		  
		 
		 
     }

	 for(i=0;i<Nc;++i)
      {
	       centro[i] = cvPoint( BoundBox[i].center.x,BoundBox[i].center.y);
      }


	

	 for(i=0;i<Nc;++i)
	 {
		 

		 if(perimetro[i]>100)
		 {
			 k=TRUE;
			 cvErode(imagen_bin,imagen_bin,element_2,1);
		 }

		
	 }



}



    

//------------------------------------------------------------------------------------------------------------------------------------------------------------


//CONOCER EL NÚMERO DE BOLAS DE CADA COLOR  Y SUS RESPECTIVAS POSICIONES




int bolas_azules=0;
int bolas_rojas=0;

int mano=0;
double radio=0.0;
CvScalar s;
CvScalar s2;


//Diferenciar bolas en el caso de que no haya bolas juntas
if( pelotas_juntas==FALSE)
{

    //Bolas azules
    for(i=0;i<Nc;++i)//bucle para todods los contornos
       {

           s=cvGet2D(Im_bolas_azules,centro[i].y,centro[i].x);//Cojo los centros y compruebo de qué color es el pixel en la imagen de bolas azules
		   if(s.val[0]==0)// si es 0,es que puede haber una bola azul o una bola rota azul
		     {
		          if(area[i]>2000 && area[i]<4000)//bola azul 
		            {
			             bolas_azules++;


			             radio=sqrt(area[i]/3.14);

			             cvCircle(
                                  im,
                                  centro[i],
                                  cvRound( radio ),
                                  CV_RGB(0x00,0xff,0xff));

			                      printf("Bola azul en:\n x=%d\n y=%d\n",centro[i].y,centro[i].x);
		             }
		     }
}


			   


	//Bolas rojas
     for(i=0;i<Nc;++i)//bucle para todos los contornos
       {
   
	       s2=cvGet2D(Im_bolas_rojas,centro[i].y,centro[i].x);//Cojo el centro y compruebo de qué color es el pixel en la imagen con bolas rojas

	       if(s2.val[0]==0)// si es 0,es que puede haber bola roja o bola rota roja
		     {
		         if(area[i]>2000 && area[i]<4000)//bola roja
		           {
			            bolas_rojas++;

			            radio=sqrt(area[i]/3.14);

			            cvCircle(
                                  im,
                                  centro[i],
                                  cvRound( radio ),
                                  CV_RGB(0xff,0x00,0x00));

			                      printf("Bola roja en:\n x=%d\n y=%d\n",centro[i].y,centro[i].x);
		           }
		   
		   
		     }
        }


		



}

if( pelotas_juntas==TRUE)
{
    float radio=30;//Como en el caso de qhe haya bolas juntas erosiono la imagen hasta separlas, no tengo las áreas reales de las bolas, así que
	              //estipulo un radio aproximado .


	//Bolas azules
    for(i=0;i<Nc;++i)
       {

          s=cvGet2D(Im_bolas_azules,centro[i].y,centro[i].x);//Cojo los centros y compruebo de qué color es el pixel en la imagen con bolas azules
		  if(s.val[0]==0)// si es 0,es que hay bola azul. En este caso no existe la posibilidad de que haya bolas rotas porque al erosionar solo permanecen los contornos
			             //con un perímetro mayor al de una bola. El perímetro de una bola rota siempre será menor
		   {
		   

			   cvCircle(
                        im,
                        centro[i],
                        cvRound( radio ),
                        CV_RGB(0x00,0xff,0xff));

			   bolas_azules++;

			   printf("Bola azul en:\n x=%d\n y=%d\n",centro[i].y,centro[i].x);





		   }
		   
		   
		

	
       }






	//Bolas rojas	
    for(i=0;i<Nc;++i)//bucle para todos los contornos
       {
   
	       s2=cvGet2D(Im_bolas_rojas,centro[i].y,centro[i].x);//Cojo el centro y compruebo de qué color es el pixel en la imagen con bolas rojas

	       if(s2.val[0]==0)// si es 0,es que hay una bola roja
		     {
		   
			     cvCircle(
                          im,
                          centro[i],
                          cvRound( radio ),
                          CV_RGB(0xff,0x00,0x00));

			     bolas_rojas++;

			     printf("Bola roja en:\n x=%d\n y=%d\n",centro[i].y,centro[i].x);
		     }
		   
		   
		
	   }

}



printf("bolas azules:%d\n",bolas_azules);
printf("bolas rotas azules:%d\n", bolas_rotas_azules);
printf("bolas rojas:%d\n",bolas_rojas);
printf("bolas rotas rojas:%d\n\n",bolas_rotas_rojas);


printf("ORDENAR AL ROBOT\n\n\n");
if(bolas_rotas_azules>0)
{
	printf("METER BOLAS AZULES DEFECTUOSAS EN CAJA DE BOLAS AZULES DEFECTUOSAS\n\n");
}

if(bolas_rotas_rojas>0)
{
	printf("METER BOLAS ROJAS DEFECTUOSAS EN CAJA DE BOLAS ROJAS DEFECTUOSAS\n\n");
}

if(bolas_azules>0 || bolas_rojas>0)
{
	printf("EMPAQUETAR BOLAS\n\n");
}



//----------------------------------------------------------------------------------------------------------------------------------------------------------------------





cvWaitKey(0);

//--------------------------------------------------------------------------------------------------------------------------------------------------------------------
//PANTALLA

cvNamedWindow("Original", CV_WINDOW_AUTOSIZE);
cvShowImage("Original", im );

//cvNamedWindow("imagen_bin", CV_WINDOW_AUTOSIZE);
//cvShowImage("imagen_bin", imagen_bin );

//Mostrar el plano de color rojo, verde y azul

//cvNamedWindow("R", CV_WINDOW_AUTOSIZE);
//cvShowImage("R",ImagenR);

//cvNamedWindow("G", CV_WINDOW_AUTOSIZE);
//cvShowImage("G",inv_bolas_azules);

//cvNamedWindow("B", CV_WINDOW_AUTOSIZE);
//cvShowImage("B",inv_bolas_rojas);

cvNamedWindow("bolas_azules", CV_WINDOW_AUTOSIZE);
cvShowImage("bolas_azules",Im_bolas_azules);

cvNamedWindow("bolas_rojas", CV_WINDOW_AUTOSIZE);
cvShowImage("bolas_rojas",Im_bolas_rojas);

//Mostrar la imagen

cvNamedWindow("Histograma de G", CV_WINDOW_AUTOSIZE);
cvShowImage("Histograma de G", histImage );

cvWaitKey(0);

//---------------------------------------------------------------------------------------------------------------------------------------------------------------

//LIBERAR MEMORIA
cvDestroyAllWindows();

cvReleaseImage(&ImagenR);
cvReleaseImage(&ImagenG);
cvReleaseImage(&ImagenB);
cvReleaseImage(&imagen_bin);
cvReleaseImage(&histImage);
cvReleaseImage(&im);
cvReleaseImage(&Imagen_RGB);
cvReleaseImage(&Imagen_umbr);
cvReleaseImage(&Imagen_umbr_2);
cvReleaseImage(&ImagenHSV);
cvReleaseImage(&ImagenH);
cvReleaseImage(&ImagenS);
cvReleaseImage(&ImagenV);
cvReleaseImage(&temp);
cvReleaseImage(&temp2);
cvReleaseImage(&temp3);
cvReleaseImage(&temp4);
cvReleaseImage(&Im_defectos_comunes);
cvReleaseImage(&Im_bolas_azules);
cvReleaseImage(&Im_bolas_rojas);
cvReleaseImage(&inv_bolas_rojas);
cvReleaseImage(&inv_bolas_azules);









}while(salir==FALSE);

return 0;


}
Beispiel #15
0
int process_frame(IplImage* frame, IplImage* h_plane, IplImage* v_plane, CvHistogram* hist_h, CvHistogram* hist_v, int Hthresh, int Vthresh)
{
	IplImage *resultF;
	int c;

	if(!frame) return -1;


	resultF = cvCreateImage( cvGetSize(frame), frame->depth, frame->nChannels );
	cvCopy(frame,resultF,NULL);

	cvShowImage("Display1", frame );

	//cvShowImage("Display", frame );
	//cvShowImage("Display", frame );

	IplImage* result = cvCreateImage( cvGetSize(h_plane ), 8, 1 );
	int width = frame->width;
	int height = frame->height;

	int h_bins = H_BINS, v_bins = V_BINS;

	int *h_s;
	h_s = malloc(sizeof(int)*h_bins);
	int *v_s;
	v_s = malloc(sizeof(int)*v_bins);

	int j;
	float pr = (float)Hthresh/100000;
	pr = pr*result->width*result->height;
	
	for(j = 0 ; j < h_bins ; j++)
	{
	  if(cvQueryHistValue_1D(hist_h,j) < pr)
	    {
	      h_s[j] = 0;//is obstical
	    }
	  else
	    {
	      h_s[j] = H_MAX;
	
	    }
	}
	pr = (float)Vthresh/1000;
	pr = pr*result->width*result->height;
	

	for(j = 0 ; j < v_bins ; j++)
	  {
	    if(cvQueryHistValue_1D(hist_v,j) < pr)
	      {
		//	printf("%f %f\n",cvQueryHistValue_1D(hist_v,j),pr);
		v_s[j] = 0;
	      }
	    else
	      v_s[j] = V_MAX;
	  	    //	    printf("%f %d %d\n",cvQueryHistValue_1D(hist_v,j),Vthresh,v_s[j]);
	    
	  }
	//	getchar();
	int i;
	CvScalar Black, White;
	Black.val[0] = 0;
	White.val[0] = 255;
	int p,q;
	cvCopy(v_plane, result,NULL);
	int h_bsize = H_MAX/H_BINS;
	int v_bsize = V_MAX/V_BINS;
	//printf("%d %d\n",h_bsize,v_bsize);
	for(i = 0 ; i < result->height ; i++)
	{
		for(j = 0 ; j < result->width ; j++)
		{
			CvScalar s;
			s = cvGet2D(h_plane ,i ,j);
			if(h_s[(int)s.val[0]/(h_bsize)]  != 0 )//obsticals are white
				cvSet2D(h_plane,i,j,Black);
			else
				cvSet2D(h_plane,i,j,White);


			s = cvGet2D(v_plane ,i ,j);
			if(s.val[0] == 255)
			  s.val[0] = 254;
			if(v_s[(int)s.val[0]/(v_bsize)]  != 0)
				cvSet2D(v_plane,i,j,Black);
			else
			  {
			    cvSet2D(v_plane,i,j,White);
			  }
		}
	}
	

	//for(i = 0; i < result->height; i++)
	//{
	//	for(j = 0; j < result->width; j++)
	//	{
	//		if(countArray[i/BLOCK_DIM][j/BLOCK_DIM] <= AMT_BLACK)
	//			cvSet2D(result, i, j, Black);			
	//		else
	//			cvSet2D(result, i, j, White);
	//	}
	//}

	cvOr(v_plane,h_plane,result,NULL);

	cvShowImage("Result", result );
	cvShowImage("HDisplay", h_plane );
	cvShowImage("VDisplay", v_plane );
	//UNCOMMENT FOR CONTOUR
	/*
	CvMemStorage* memStorage = cvCreateMemStorage(0);
	CvSeq* contours = 0;
	cvFindContours(result, memStorage, &contours,sizeof(CvContour),CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));
	CvSeq* co;
	for( co = contours; co != NULL; co = co->h_next) 
	{
		cvDrawContours(resultF,co,cvScalarAll(0),cvScalarAll(0),-1,5,8,cvPoint(0,0));
	}
	cvShowImage("FinalDisplay", resultF );
	cvReleaseMemStorage(&memStorage);
	*/
	//comment stops here
	cvReleaseImage(&result );
	cvReleaseImage(&resultF );
	free(h_s);
	free(v_s);
	c = cvWaitKey(30);
	if( c == 'q' || c == 'Q' || (c & 100) == 27 )
		return -1;
	return 0;
}