RSS
 

Archive for the ‘OpenCV’ Category

OpenCV: Adaptive threshold

29 Aug

[ad#AdBrite inline]

//src is IPL_DEPTH-8U, 3 channels
IplImage* gray = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U , 1);
cvCvtColor(src ,gray, CV_RGB2GRAY);

double parameters[2];
double minDisp = 40;

double mean, stdDev;

cvMean_StdDev(gray, &mean, &stdDev);
parameters[0]=(double)2;
parameters[1]=(double) stdDev * 0.9;

cvAdaptiveThreshold(gray,gray,
double(255),
   	CV_STDDEV_ADAPTIVE_THRESH,
CV_THRESH_BINARY,

parameters);

[ad#AdBrite inline]

 
No Comments

Posted in OpenCV

 

OpenCV: Change contrast and brightness of an image

29 Aug

[ad#AdBrite inline]

// CHANGES BRIGHTNESS AND/OR CONTRAST
// INPUT: 	IplImage * (nChannels=1 OR nChannels=3; IPL_DEPTH_8U)
// RETURNS: 	IplImage * SAME DEPTH AND CHANNELS AS INPUT

IplImage * ContrastBrightness(IplImage *src, int Contrast, int Brightness)

{

	if(Contrast > 100) Contrast = 100;
	if(Contrast < -100) Contrast = -100;
	if(Brightness > 100) Brightness = 100;
	if(Brightness < -100) Brightness = -100;

	uchar lut[256];

	CvMat* lut_mat;
	int hist_size = 256;
	float range_0[]={0,256};
	float* ranges[] = { range_0 };

	int i;

	IplImage * dest = cvCloneImage(src);

	IplImage * GRAY = cvCreateImage(cvGetSize(src),src->depth,1);

	if (src->nChannels ==3)
	{
		cvCvtColor(src,GRAY,CV_RGB2GRAY);
	}
	else
	{
		cvCopyImage(src,GRAY);
	}

    lut_mat = cvCreateMatHeader( 1, 256, CV_8UC1 );
    cvSetData( lut_mat, lut, 0 );

	 /*
     * The algorithm is by Werner D. Streidt
     * (http://visca.com/ffactory/archives/5-99/msg00021.html)
     */

	if( Contrast > 0 )

    {
        double delta = 127.* Contrast/100;
        double a = 255./(255. - delta*2);
        double b = a*(Brightness - delta);
        for( i = 0; i < 256; i++ )
        {
            int v = cvRound(a*i + b);

            if( v < 0 )
                v = 0;
            if( v > 255 )
                v = 255;
            lut[i] = v;
        }
    }
    else
    {
        double delta = -128.* Contrast/100;

        double a = (256.-delta*2)/255.;
        double b = a* Brightness + delta;
        for( i = 0; i < 256; i++ )
        {
            int v = cvRound(a*i + b);
            if( v < 0 )
                v = 0;

            if( v > 255 )
                v = 255;
            lut[i] = v;
        }
    }

	if (src->nChannels ==3)
	{

		IplImage * R = cvCreateImage(cvGetSize(src),src->depth,1);

		IplImage * G = cvCreateImage(cvGetSize(src),src->depth,1);
		IplImage * B = cvCreateImage(cvGetSize(src),src->depth,1);

		cvCvtPixToPlane(src,R,G,B,NULL);

		// PERFORM IT ON EVERY CHANNEL
		cvLUT( R, R, lut_mat );

		cvLUT( G, G, lut_mat );
		cvLUT( B, B, lut_mat );

		cvCvtPlaneToPix(R,G,B,NULL,dest);

		cvReleaseImage(&R);
		cvReleaseImage(&G);
		cvReleaseImage(&B);

	}
	else
	{

		//PERFORM IT ON THE CHANNEL
		cvLUT( GRAY, dest, lut_mat );
	}

	cvReleaseImage(&GRAY);
	cvReleaseMat( &lut_mat);

	return dest;

}

[ad#AdBrite inline]

 
1 Comment

Posted in OpenCV

 

OpenCV: Otsu thresholding

25 Aug

I found this beautiful piece of code in the mailing list of OpenCV. I thought to share it with you and in the same time to archive it for future use.

[ad#AdBrite inline]

//----------------------------------------------------------
// binarisation otsu
//----------------------------------------------------------
#include "iostream"
#include "stdio.h"
#include "stdlib.h"
#include "math.h"
#include "time.h"
#include "cxcore.h"
#include "cv.h"
#include "highgui.h"

int GRAYLEVEL = 256;
#define MAX_BRIGHTNESS 255
//const double INFO_THRESHOLD = 0.2;

using namespace std;

//----------------------------------------------------------
// binarization by Otsu's method
// based on maximization of inter-class variance
//----------------------------------------------------------
void binarize_otsu(IplImage* image, IplImage* imgBin )
{
int hist[GRAYLEVEL];
double prob[GRAYLEVEL],
omega[GRAYLEVEL]; // prob of graylevels
double myu[GRAYLEVEL]; // mean value for separation
double max_sigma,
sigma[GRAYLEVEL]; // inter-class variance

int i, x, y; /* Loop variable */
int threshold; /* threshold for binarization */

// Histogram generation
memset((int*) hist , 0, GRAYLEVEL * sizeof(int) );

CvSize size = cvGetSize(image);

for (int i = 0; i < size.height; ++i)
{
unsigned char* pData = (unsigned char*) (image->imageData + i *
image->widthStep);
for (int j = 0; j < size.width; ++j)
{
int k = (int)((unsigned char) *(pData+j));
hist[k]++;
}
}

int taille = size.width * size.height;

// calculation of probability density
for ( i = 0; i < GRAYLEVEL; ++i )
{
prob[i] = (double) ((double)hist[i] / (double)taille);
}

/*
int LEVEL = GRAYLEVEL;
double sumProb = 0.0;
for ( i = 0; i < GRAYLEVEL; ++i )
{
sumProb += prob[i];
if ( sumProb > INFO_THRESHOLD)
{
LEVEL = i;
break;
}
}
GRAYLEVEL = LEVEL;
*/

// omega & myu generation
omega[0] = prob[0];
myu[0] = 0.0;
for (i = 1; i < GRAYLEVEL; i++)
{
omega[i] = omega[i-1] + prob[i];
myu[i] = myu[i-1] + (i*prob[i]);
}

//----------------------------------------------------------
// sigma maximization
// sigma stands for inter-class variance
// and determines optimal threshold value
//----------------------------------------------------------
threshold = 0;
max_sigma = 0.0;
for (i = 0; i < GRAYLEVEL-1; i++)
{
if (omega[i] != 0.0 && omega[i] != 1.0)
{
//sigma[i] = (omega[i]*(1.0 - omega[i])) * ((myu[GRAYLEVEL-1] - 2*myu[i]) *
(myu[GRAYLEVEL-1] - 2*myu[i]));
sigma[i] = ((myu[GRAYLEVEL-1]*omega[i] - myu[i]) *
(myu[GRAYLEVEL-1]*omega[i] - myu[i])) / (omega[i]*(1.0 - omega[i]));
}
else
{
sigma[i] = 0.0;
}
if (sigma[i] > max_sigma)
{
max_sigma = sigma[i];
threshold = i;
}
}

printf("threshold = %d\n", threshold);

// binarization output into imgBin
for (y = 0; y < size.height; ++y)
{
unsigned char* pData = (unsigned char*) (image->imageData + (y *
image->widthStep));
unsigned char* pDataBin = (unsigned char*) (imgBin->imageData + (y *
imgBin->widthStep));
for (x = 0; x < size.width; ++x)
{
if ( *(pData+x) > threshold)
{
*(pDataBin+x) = MAX_BRIGHTNESS;
}
else
{
*(pDataBin+x) = 0;
}
}
}

}

int main(int argc, char* argv[] )
{
IplImage* image = 0;
IplImage* imgBin = 0;
clock_t start = clock();
(argc == 3) ? image = cvLoadImage(argv[1], CV_LOAD_IMAGE_GRAYSCALE) :
cout < < "Usage :\n" << argv[0] << " [srcImagePath] [dstimagepath]" < < endl;

if ( image != NULL )
{
imgBin = cvCloneImage(image);
binarize_otsu(image,imgBin );
cvSaveImage(argv[2], imgBin);
cvReleaseImage(&image);
cvReleaseImage(&imgBin);
clock_t end = clock();
double delay = double((double)(end - start) / CLOCKS_PER_SEC);
printf("processing time : %lf seconds\n",delay);
return EXIT_SUCCESS;
}

return EXIT_FAILURE;
}

[ad#AdBrite inline]

 
1 Comment

Posted in OpenCV

 

OpenCV: Homography Matrix

22 Aug

As it is well explained in Wikipedia. The Homography matrix given:
|h1 h2 h3|
|h4 h5 h6|
|h7 h8 h9|
It is used to express the relationship between a source point and a destination point and vis-versa.
You want to map src -> dst and therefore find the homography matrix using openCV function. Then :
dst.x = (src.x*h1+src.y*h2+h3 )/(src.x*h7+src.y*h8+h9);
dst.y = (src.x*h4+src.y*h5+h6 )/(src.x*h7+src.y*h8+h9);

The function is :

public static void cvFindHomography(
IntPtr srcPoints,
IntPtr dstPoints,
IntPtr homography,
HOMOGRAPHY_METHOD method,
double ransacReprojThreshold,
IntPtr mask
)

[ad#AdBrite inline]

 
No Comments

Posted in OpenCV

 

OpenCV: Image cropping

01 Aug

Here is a useful function to crop an image or to get the region of interest (ROI).

IplImage* crop( IplImage* src,  CvRect roi){
  // Must have dimensions of output image
  IplImage* cropped = cvCreatImage( cvSize(roi.width,roi.height), src->depth, src->nChannels )

  // Say what the source region is
  cvSetImageROI( src, roi );

  // Do the copy
  cvCopy( src, cropped );
  cvResetImageROI( src );

  return cropped;
}

[ad#Amazon Opencv]

usage will be like this:

IplImage* cropped = crop(source, cvRect( 0,0, 1280,500 ));

Be careful not to give a cvRect bigger then source image. It will crash your program with an awful error message.

 
3 Comments

Posted in OpenCV