Archive

Archive for the ‘My Original Post’ Category

Bayes’ Theorem Visualization by Venn Diagram

October 28, 2012 1 comment

Almost all of the math books only give logical explanations of Bayes’ Theorem. Sometimes it is hard to intuitively understand how it comes . I’m trying to visualize the theorem by Venn diagram. Actually, it is a very simple concept.  I don’t understand why don’t these math book authors put such a picture into book to help people understand, or they don’t want their book appears easy? I took probability courses in high school, undergrad and grad, but I’ve never seen a similar approach to elaborate this problem.

Bayes’ Theorem

P[A_j|B] = \frac{P[B|A_j] P[A_j]}{P[B]}

There are several events A_j are mutually exclusive and divide universal space S into several parts.

We assume event B occurs when  A_j happen.

 

Assume we already know P[A_j], P[B] and P[B|A_j] , then we can get P[A_j|B] .

P[B|A_j] is a priori,

P[A_j|B] is a posteriori.

Categories: My Original Post

Census Transform – C++ Implementation

September 8, 2012 4 comments

Census Transform is a non-parametric local transform proposed by Zabih and Woodfill[1] in 1994.  Robust and insensitive to various brightness and contrast images is the primary advantage of the transform. The census transform is rather simple

12 58 66          1 1 1

50 70 81   =>  1    0  => 111 1 0 101b  => 245d

35 92 11          1 0 1

For example, we define a 3×3 sliding window to scan the entire image, and compare every pixels with center pixel.

If(PixelIntensity < PixelIntensityCenter)

bit =  1;

else

bit = 0;

then shift the bit to the left.

Do the same job to complete the all elements in the window and move the window to next pixel.

As we can see, the transform only reflect the relative brightness of a pixel to its neighbors. So it is an ideal way to reveal the structure of an image.

imL_original

imL_highcontrast

imL_lowcontrast

////////////////////////////////////////////////////////////////

img33_original

img33_highcontrast

img33_lowcontrast

Pay attention to the low-texture area, the census transform is still powerful to extract the structure inside such areas, which would facilitate stereo matching algorithms to find similarities between image pairs even in low-texture areas.

=======================

I continuously get wrong calculation results from my code at one time, so be careful.

Mat imgIn = imread(imgName, 0);
Mat imgTemp = imgIn;//try to copy the mat, but it is wrong

 #include <iostream>
 #include <sstream>

 #include "opencv2/core/core.hpp"
 #include "opencv2/core/opengl_interop.hpp"
 #include "opencv2/highgui/highgui.hpp"
 #include "opencv2/imgproc/imgproc.hpp"
 #include "opencv2/calib3d/calib3d.hpp"
 #include "opencv2/contrib/contrib.hpp"

 using namespace std;
 using namespace cv;

int main(int argc, char** argv)
 {
 const char* imgName = "imL_re.png";
 Mat imgIn = imread(imgName, 0);
 imshow("input", imgIn);
 Size imgSize = imgIn.size();
 Mat imgTemp = Mat::zeros(imgSize, CV_8U);

 //If (CurrentPixelIntensity<CentrePixelIntensity) boolean bit=0
 //else boolean bit=1
 //450jx375i

 unsigned int census = 0;
 unsigned int bit = 0;
 int m = 3;
 int n = 3;//window size
 int i,j,x,y;
 int shiftCount = 0;
 for (x = m/2; x < imgSize.height - m/2; x++)
 {
   for(y = n/2; y < imgSize.width - n/2; y++)
   {
     census = 0;
     shiftCount = 0;
     for (i = x - m/2; i <= x + m/2; i++)
     {
       for (j = y - n/2; j <= y + n/2; j++)
       {

         if( shiftCount != m*n/2 )//skip the center pixel
         {
         census <<= 1;
         if( imgIn.at<uchar>(i,j) < imgIn.at<uchar>(x,y) )//compare pixel values in the neighborhood
         bit = 1;
         else
         bit = 0;
         census = census + bit;
         //cout<<census<<" ";*/

         }
         shiftCount ++;
       }
     }
    //cout<<endl;

    imgTemp.ptr<uchar>(x)[y] = census;
   }
 }

 imshow("output", imgTemp);
 waitKey();
 return 0;

}

===================
[1]http://www.cs.duke.edu/courses/spring06/cps296.1/handouts/Zabih%20Woodfill%201994.pdf

Matrix/Array Argument Passing in OpenCV

September 7, 2012 Leave a comment

It is convenient to pass Mat to a function, which is one of the most frequently used argument passing in image processing. Actually, no real array elements (matrix) can be passed to a function, array pointers are the arguments that are passed to a function.

In OpenCV, Mat is an image, image is a Mat.

func(Mat src, Mat dst)
{
    ......
    //example
    for(int i=0, i<imax, i++)
       for(int j=0, j<jmax, j++)
          if(src.at<uchar>(i,j) == blabla)
              dst.at<uchar>(i,j) = blabla;
    ......
}

//another method used by opencv stock functions
func(Inputarry _src, Outputarry _dst)
{
    Mat src = _src.getmat();
    _dst.creat(src.size(), src.type());
    Mat dst = _dst.getmat();

    for(int i=0, i<imax, i++)
       for(int j=0, j<jmax, j++)
          if(src.at<uchar>(i,j) == blabla)
             dst.at<uchar>(i,j) = blabla;
    ......
}
Categories: CV, My Original Post

2D dynamic array using Vector and Mat in C++/OpenCV

August 31, 2012 Leave a comment

In my previous post, a dynamic 2D array can be implemented by malloc function. However, it is kind of tricky and takes many lines to complete. Here is an easy method at the expense of speed in C++.

int m, n//rows and cols

//caution!!! space between" > >" in "...vector<int> >"

vector< vector<int> > array(m, vector<int>(n,0));

In OpenCV library, 2D dynamic array could be initialized by cv::Mat


using namespace cv;

Mat array;

int m,n; //rows and cols

Mat::zeros(m, n, CV_8U); //initialize all elements to 0, 8-bit depth, i.e. unsigned char

It is extremely simple and efficient.

In addition, new function is another C++ implementation which actually simplified version of malloc.

int **array=new int*[row];
for(i=0; i<row; i++)
 array[i]=new int[col];
Categories: My Original Post

Weird VS2010 Project Properties sheets

July 15, 2012 Leave a comment

Trying to build new opencv project with default include paths

D:\Program Files\OpenCV242\build\myx86\install\include

D:\Program Files\OpenCV242\build\myx86\install\lib

and linker input files

opencv_calib3d242d.lib; opencv_contrib242d.lib; opencv_core242d.lib; opencv_features2d242d.lib; opencv_flann242d.lib; opencv_gpu242d.lib; opencv_highgui242d.lib; opencv_imgproc242d.lib; opencv_legacy242d.lib; opencv_ml242d.lib; opencv_objdetect242d.lib; opencv_ts242d.lib; opencv_video242d.lib;

If I put all of these information into

C:\Users\bf109\AppData\Local\Microsoft\MSBuild\v4.0\Microsoft.Cpp.Win32.user.props

The project can be built normally, but the exe can not read command line arguments.

I have to restore Microsoft.Cpp.Win32.user.props into original status:

<?xml version=”1.0″ encoding=”utf-8″?>
<Project DefaultTargets=”Build” ToolsVersion=”4.0″ xmlns=”http://schemas.microsoft.com/developer/msbuild/2003″&gt;

</Project>

Then the exe can read args normally.

Don’t understand Microsoft.

Categories: My Original Post

Camshift Infrared Tracking – F-22

April 23, 2012 Leave a comment

Infrared object tracking project, which utilizes OpenCV library and developed in VC++ environment. Camshift algorithm is applied to find the local maximum in the histogram segmented binary frame. To predict the movement of object and smooth the tracking box, I added Kalman filter to the output coordinates..

Source code link

 

===========================

2D dynamic array for arbitrary image size – C/C++ implementation

April 16, 2012 Leave a comment

If we would like to read an arbitrary size image and do processing algorithms, fixed size 2D data array is not applicable. A dynamic allocating technique is using malloc function.

It is easier to malloc 1D array into a heap. But this will result in harder works for indexing the 1D array since an image is 2D.

Thus we have to do the following code to allocate 2D dynamic array in a heap within a subroutine function, which can be called in main function. Never forget to free the heap after use to prevent from memory leak.

unsigned char * bndfollow(unsigned char *in, int m,int n)
{
 int i,j;
 //allocating dynamic 2D array - input data array
 unsigned char** data_in=(unsigned char**)malloc(sizeof(unsigned char *) * m);//new int*[m];
 data_in[0] = (unsigned char *)malloc(sizeof(unsigned char) * m * n);//allocating memory continuously
 for(i=0; i<m; i++)
 {
   data_in[i+1] = data_in[i] + n;
 }

 for(i=0;i<m;i++)
 {
   for (j=0;j<n;j++)
   {
     data_in[i][j]=0;
  // printf("%d ", data_in[i][j]);
   }
 }

 for(i=0;i<m;i++)
 {
   for (j=0;j<n;j++)
   {
     data_in[i][j]=in[i*n+j];//initializing all elements
  // printf("%d ", data_in[i][j]);
   }
 }

// processing data_in[][]

//...

// put output data to data_out[][]

//allocating dynamic 2D array, output
 unsigned char** data_out=(unsigned char**)malloc(sizeof(unsigned char *) * m);//new int*[m];
 data_out[0] = (unsigned char *)malloc(sizeof(unsigned char) * m * n);//
 for(i=1; i<m; i++)
 {
   data_out[i] = data_out[i-1] + n;
 }
 for(i=0;i<m;i++)
 {
   for (j=0;j<n;j++)
   {
     data_out[i][j]=0;
  // printf("%d ", data_in[i][j]);
   }
 }
 //put bound data to output array

 for(i=0;i<m;i++)
 {
   for (j=0;j<n;j++)
   {
     data_out[i][j]=data_scan1[i][j]*255;
   }

 }

 return &data_out[0][0];// return the heap pointer
}
int main()
{

 //calling the subroutine

 unsigned char *book_bnd=bndfollow(&book_rot[0][0],256,256);

 //...

}
Categories: My Original Post