Sort blobs generated by cvBlobsLib by areas.

May 18, 2011

cvBlobsLib is an useful OpenCV 3rd party library to do blob analysis. However the blobs extracted are sorted based on their y coordinates and the author provided no interface to sort the blobs by other criteria such as area. To do so, you need to make some internal change. Add the following member function that sort the blobs based on their areas to the class CBlobResult.

    // sort blobs
    void SortBlobs()
    {
        struct myclass {
            bool operator() (CBlob* b1,CBlob* b2)
            {
                return (b1->GetArea() < b2->GetArea());
            }
        } blobComp;

        std::sort(m_blobs.begin(),m_blobs.end(),blobComp);
    }

If you want to sort the blobs based on their x coordinates, change the 7th line of above code to

return (b1->GetBoundingBox().x < b2->GetBoundingBox().x);

.


De Boor’s Algorithm in C++

October 18, 2009

Here is the c++ code for the De Boor algorithm. It calculates a point C(x) on a B-Spline curve of any degree.

Point deBoor(int k,int degree, int i, double x, double* knots, Point *ctrlPoints)
{   // Please see wikipedia page for detail
	// note that the algorithm here kind of traverses in reverse order
	// comapred to that in the wikipedia page
	if( k == 0)
		return ctrlPoints[i];
	else
	{   
		double alpha = (x-knots[i])/(knots[i+degree+1-k]-knots[i]);
		return (deBoor(k-1,degree, i-1, x, knots, ctrlPoints)*(1-alpha )+deBoor(k-1,degree, i, x, knots, ctrlPoints)*alpha );
	}
}

The Point class is defined as the follow:

class Point
{
public:
	Point(){x=0.;y=0.;z=0.;};
	// copy operator
	Point operator=(const Point pt) ;
	Point operator+(const Point pt) const;
	//Point operator-(const Point pt) const;
	Point operator*(double m) const;
	Point operator/(double m) const;
	double x,y,z;
};

Point Point::operator=(const Point pt)
{
	x = pt.x;
	y = pt.y;
	z = pt.z;
	return *this;
}
Point Point::operator+(const Point pt) const
{
	Point temp;
	temp.x = x + pt.x;
	temp.y = y + pt.y;
	temp.z = z + pt.z;
	return temp;
}
Point Point::operator*(double m) const
{
	Point temp;
	temp.x = x*m;
	temp.y = y*m;
	temp.z = z*m;
	return temp;
}
Point Point::operator/(double m) const
{
	Point temp;
	temp.x = x/m;
	temp.y = y/m;
	temp.z = z/m;
	return temp;
}

3D mesh correspondence selection tool

July 31, 2008

This is a program that allows users to manually assign corresponding triangles between two triangular meshes. Currently it only supports triangular-only meshs. To compile the code, run make PROG=hw3c.

User has to first click on a triangle from the model on the left window and select its corresponding triangle from the model on the right. The index of corresponding facets will be stored. Press ‘w’ to save the correspondences into file “cr.txt”. You will have to backup the old cr.txt yourself.

User can rotate each model individually by moving the mouse and hold the right mouse button and zoom in/out by using the mouse wheel. If the mouse wheel is not responding, use key ‘z’ and ‘x’ to zoom in and out. Press ‘Esc’ to exit the program.

Source code can be downloaded here.

Screeshot of the program

Screeshot of the program


Calculation of matrix inverse in C/C++

May 28, 2008

Below is the code to calculate matrix inverse of a matrix of arbitrary size (order) by using analytic solution. This method is known to be slow for very large matrix because of the recursion. However, I used this mainly for calculating inverse of 4×4 matrices and it worked just fine. You can also use CalcDeterminant and GetMinor to calculate determinant of a matrix.

MatrixInversion: the main function to calculate the inverse matrix.
CalcDeterminant
: calculate the determinant of a matrix.
GetMinor:
Get minor matrix.

Read the rest of this entry »


Be aware of memory alignment of IplImage in OpenCV

May 7, 2008

The imageData of IplImage is aligned 4 or 8 bytes in order to enhance the processing speed. For example, let’s say you have a color image of size 98-by-98 (pixel depth 8 bits ) and imageData is aligned 4 bytes. The size of each row will not be 98×3=294 bytes but 296 bytes. The widthStep of IplImage shows the actual size of aligned image row in bytes. This can help us access imageData correctly. Here is a code that copy imageData to a user-created buffer.

//
IplImage *colorImage;
// load an color image
colorImage = cvLoadImage("SL_0230.jpg");
// create a temp buffer
unsigned char *buffer,*temp2;
buffer = new unsigned char[colorImage->width*colorImage->height*colorImage->nChannels];
temp2 = buffer;

// pointer to imageData
unsigned char *temp1 = (unsigned char*) colorImage->imageData;
// copy imagedata to buffer row by row
for(int i=0;i<colorImage->height;i++)
{
    // memory copy
    memcpy(temp2, temp1, colorImage->width*colorImage->nChannels);
    // imageData jump to next line
    temp1 = temp1 + colorImage->widthStep;
    // buffer jump to next line
    temp2 = temp2+ colorImage->width*colorImage->nChannels;
}
// ......................
//.....