Home > My CV Project, My Original Post > Census Transform – C++ Implementation

Census Transform – C++ Implementation

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

  1. atul
    June 15, 2016 at 6:43 am

    Does the census transform work on only one image or it works on two images
    like matching of 2 different images.
    Also the output of census transform is just used for matching or it represents the intensity value.

    • June 16, 2016 at 4:21 am

      Census transform can work on two images. You can use it to extract information for matching.

      • atul
        June 16, 2016 at 5:32 am

        thankyou sir

  2. atul
    June 19, 2016 at 9:51 pm

    i have one more question regarding this… as said by you we can use this for matching two images from the census vector .

    But here in the code above you have used only one image and the output census vector is used as pixel intensity value to display the output image.

    But as per the paper the output census vector does not represent pixel intensity value.
    It is only the vector representation for matching two images.
    So the above output image is not a valid output of census transform??

  1. No trackbacks yet.

Leave a comment