原文地址http://blog.sina.com.cn/s/blog_684c8d630100turx.html
一、Census Transform(CT)算法的学习
123 | 127 | 129 |
126 | 128 | 129 |
127 | 131 | 130 |
然后比较此窗口中每个像素值(中心除外)与中心像素值的大小,如果比中心像素值小,则比较结果为1,否则为0。由此,得到如下结果:
1 | 1 | 0 |
1 | 0 | |
1 | 0 | 0 |
然后,把此窗口结果组成一个序列:11010100,以此二进制序列表示的值来代替原图像窗口中心点的像素。如此下去,等到窗口滑动完整幅图像,我们就得到原图像做统计变换(CT)之后的图像。
注意:只能作用于灰度图像,对于彩色图像,则需要转换为灰度图之后再操作;为了简单起见,我没有考虑图像的边缘像素值。
% *************************************************************************
% Title: Function-Census Transform of a given Image
% Author: Siddhant Ahuja
% Created: May 2008
% Copyright Siddhant Ahuja, 2008
% Inputs: Image (var: inputImage), Window size assuming square window (var:
% windowSize) of 3x3 or 5x5 only.
% Outputs: Census Tranformed Image (var: censusTransformedImage),
% Time taken (var: timeTaken)
% Example Usage of Function: [a,b]=funcCensusOneImage('Img.png', 3)
% *************************************************************************
function [censusTransformedImage, timeTaken] = funcCensusOneImage(inputImage, windowSize)
% Grab the image information (metadata) using the function imfinfo
try
imageInfo = imfinfo(inputImage);
% Since Census Transform is applied on a grayscale image, determine if the
% input image is already in grayscale or color
if(getfield(imageInfo,'ColorType')=='truecolor')
% Read an image using imread function, convert from RGB color space to
% grayscale using rgb2gray function and assign it to variable inputImage
inputImage=rgb2gray(imread(inputImage));
else if(getfield(imageInfo,'ColorType')=='grayscale')
% If the image is already in grayscale, then just read it.
inputImage=imread(inputImage);
else
error('The Color Type of Input Image is not acceptable. Acceptable color types are truecolor or grayscale.');
end
end
catch
inputImage = inputImage;
end
% Find the size (columns and rows) of the image and assign the rows to
% variable nr, and columns to variable nc
[nr,nc] = size(inputImage);
% Check the size of window to see if it is an odd number.
if (mod(windowSize,2)==0)
error('The window size must be an odd number.');
end
if (windowSize==3)
bits=uint8(0);
% Create an image of size nr and nc, fill it with zeros and assign
% it to variable censusTransformedImage of type uint8
censusTransformedImage=uint8(zeros(nr,nc));
else if (windowSize==5)
bits=uint32(0);
% Create an image of size nr and nc, fill it with zeros and assign
% it to variable censusTransformedImage of type uint32
censusTransformedImage=uint32(zeros(nr,nc));
else
error('The size of the window is not acceptable. Just 3x3 and 5x5 windows are acceptable.');
end
end
% Initialize the timer to calculate the time consumed.
tic;
% Find out how many rows and columns are to the left/right/up/down of the
% central pixel
C= (windowSize-1)/2;
for j=C+1:1:nc-C % Go through all the columns in an image (minus C at the borders)
for i=C+1:1:nr-C % Go through all the rows in an image (minus C at the borders)
census = 0; % Initialize default census to 0
for a=-C:1:C % Within the square window, go through all the rows
for b=-C:1:C % Within the square window, go through all the columns
if (~(a==0 && b==0)) % Exclude the centre pixel from the calculation,原来是(C+1),现改为0
census=bitshift(census,1); %Shift the bits to the left by 1
% If the intensity of the neighboring pixel is less than
% that of the central pixel, then add one to the bit
% string
if (inputImage(i+a,j+b) < inputImage(i,j))
census=census+1;
end
end
end
end
% Assign the census bit string value to the pixel in imgTemp
censusTransformedImage(i,j) = census;
end
end
% Stop the timer to calculate the time consumed.
timeTaken=toc;
二、Modified Census Transform (MCT)算法
1 | 1 | 0 |
1 | 0 | 0 |
1 | 0 | 0 |
三、Revised Modified Census Transform (RMCT)算法
#include "stdafx.h"
#include "MCT.h"
#include "highgui.h"
MCT::MCT()
{
window_size = 0;
}
MCT::~MCT()
{
}
void MCT::ModifiedCensusTransform(IplImage *input_image, IplImage *mct_image, const int window_size, const int delta )
{
CvSize image_size = cvGetSize(input_image);
int image_width = image_size.width;
int image_height = image_size.height;
IplImage *gray_image = cvCreateImage(cvGetSize(input_image), input_image->depth, 1);
cvSetZero(gray_image);
if(input_image->nChannels != 1)
{
cvCvtColor(input_image, gray_image, CV_RGB2GRAY);
}
else
{
cvCopy(input_image, gray_image);
}
IplImage *modified_image = NULL;
switch (window_size)
{
case 3:
modified_image = cvCreateImage(image_size, IPL_DEPTH_16U, 1);
cvSetZero(modified_image);
break;
case 5:
modified_image = cvCreateImage(image_size, IPL_DEPTH_32S, 1);
cvSetZero(modified_image);
break;
default:
printf("window size must be 3 or 5!\n");
exit(EXIT_FAILURE);
}
CvMat window;
for(int i = 0; i < image_height - window_size; i++)
{
for(int j = 0; j < image_width - window_size; j++)
{
unsigned long census = 0;
CvRect roi = cvRect(j, i, window_size, window_size);
cvGetSubRect(gray_image, &window, roi);
CvScalar m = cvAvg(&window, NULL);
for(int w = 0; w < window_size; w++)
{
for(int h = 0; h < window_size; h++)
{
census = census << 1; //左移1位
double tempvalue = cvGetReal2D(&window, w, h);
if(tempvalue < m.val[0] + delta)
census += 1;
}
}
cvSetReal2D(modified_image, i, j, census);
}
}
//cvConvertScaleAbs(modified_image, mct_image, 1, 0);
Normalize(modified_image, mct_image);
cvReleaseImage(&gray_image);
cvReleaseImage(&modified_image);
}
void MCT::Normalize(IplImage *mct_image, IplImage *nor_image)
{
double minv, maxv;
cvMinMaxLoc(mct_image, &minv, &maxv);
for (int i = 0; i < mct_image->height; i++)
{
for (int j = 0; j < mct_image->width; j++)
{
double tempv = cvGetReal2D(mct_image, i, j);
tempv = (tempv - minv) / (maxv - minv) * 255;
cvSetReal2D(nor_image, i, j, tempv);
}
}
}
由于算法比较简单,所以没有写注释,应该比较容易理解。
四、CT/MCT/RMCT的应用
1、《Face Detection with the Modified CensusTransform》(前面提到的那篇)
2、《Adaboost Based Disguised Face Discrimination on EmbeddedDevices》
3、《Disguised-Face Discriminator for Embedded Systems》
OVER!