基于护照的识别和特征提取,使用opencv2.4.9在VS2012里做的。直接上代码:
#include
#include
#include
using namespace cv;
using namespace std;
#define image_name "z001z.bmp"
#define corrode_index 1 //腐蚀指数
int otsu(const IplImage *src_image) //大津法求阈值
{
double sum = 0.0;
double w0 = 0.0;
double w1 = 0.0;
double u0_temp = 0.0;
double u1_temp = 0.0;
double u0 = 0.0;
double u1 = 0.0;
double delta_temp = 0.0;
double delta_max = 0.0;
//src_image灰度级
int pixel_count[256]={0};
float pixel_pro[256]={0};
int threshold = 0;
uchar* data = (uchar*)src_image->imageData;
//统计每个灰度级中像素的个数
for(int i = 0; i < src_image->height; i++)
{
for(int j = 0;j < src_image->width;j++)
{
pixel_count[(int)data[i * src_image->width + j]]++;
sum += (int)data[i * src_image->width + j];
}
}
cout<<"平均灰度:"<
for(int i = 0; i < 256; i++)
{
pixel_pro[i] = (float)pixel_count[i] / ( src_image->height * src_image->width );
}
//遍历灰度级[0,255],寻找合适的threshold
for(int i = 0; i < 256; i++)
{
w0 = w1 = u0_temp = u1_temp = u0 = u1 = delta_temp = 0;
for(int j = 0; j < 256; j++)
{
if(j <= i) //背景部分
{
w0 += pixel_pro[j];
u0_temp += j * pixel_pro[j];
}
else //前景部分
{
w1 += pixel_pro[j];
u1_temp += j * pixel_pro[j];
}
}
u0 = u0_temp / w0;
u1 = u1_temp / w1;
delta_temp = (float)(w0 *w1* pow((u0 - u1), 2)) ;
if(delta_temp > delta_max)
{
delta_max = delta_temp;
threshold = i;
}
}
return threshold;
}
void front(IplImage *imgdst )//前面图片处理
{
IplImage* img_black = cvCreateImage(cvGetSize(imgdst),IPL_DEPTH_8U,1);
cvSet(img_black,cvScalar(0),NULL);
cvSetImageROI(imgdst, cvRect(8, 145, 162, 255)); //为图象设置ROI区域
cvSetImageROI(img_black, cvRect(8, 145, 162, 255));
cvCopy(imgdst,img_black,NULL);
cvResetImageROI(imgdst);
cvResetImageROI(img_black);
cvSetImageROI(imgdst, cvRect(285, 122,245,245)); //为图象设置ROI区域
cvSetImageROI(img_black, cvRect(285, 122,245,245));
cvCopy(imgdst,img_black,NULL);
cvResetImageROI(imgdst);
cvResetImageROI(img_black);
cvSaveImage("正面结果.jpg",img_black);
cvShowImage("copy.jpg",img_black);
cvWaitKey(0);
}
void back(IplImage *imgsrc ,IplImage *imgdst)//后面图片处理
{
IplImage* img_back = cvCreateImage(cvGetSize(imgdst),IPL_DEPTH_8U,1);
cvAdd(imgsrc,imgdst,img_back);
//创建纯黑图
IplImage* img_black = cvCreateImage(cvGetSize(imgdst),IPL_DEPTH_8U,1);
cvSet(img_black,cvScalar(0),NULL);
cvSetImageROI(img_back, cvRect(22,22,727,477)); //为图象设置ROI区域
cvSetImageROI(img_black, cvRect(22,22,727,477));
cvCopy(img_back,img_black,NULL);
cvResetImageROI(img_back);
cvResetImageROI(img_black);
cvSaveImage("反面结果.jpg",img_black);
cvShowImage("copy.jpg",img_black);
cvWaitKey(0);
}
int main()
{
IplImage *imgsrc = cvLoadImage(image_name,1);
if (!imgsrc)
{
cout<<"Could not open or find the image!"<
}
IplImage* imgdst =NULL;
imgdst=cvCreateImage(cvGetSize(imgsrc),IPL_DEPTH_8U,1);
IplImage* img_temp =NULL;
img_temp=cvCreateImage(cvGetSize(imgsrc),IPL_DEPTH_8U,1);
//灰度化
cvCvtColor(imgsrc,imgdst,CV_BGR2GRAY);
cvSaveImage("灰度化.jpg",imgdst);
imgsrc=imgdst;
int height = imgsrc->height; // 图像高度
int width = imgsrc->width; // 图像宽度(像素为单位)
int step = imgsrc->widthStep; // 相邻行的同列点之间的字节数
int channels = imgsrc->nChannels; // 颜色通道数目 (1,2,3,4)
uchar *data = (uchar *)imgsrc->imageData;
//反色操作
for(int i=0;i != height; ++ i)
{
for(int j=0;j != width; ++ j)
{
for(int k=0;k != channels; ++ k)
{
data[i*step+j*channels+k]=255-data[i*step+j*channels+k];
}
}
}
cvSaveImage("反色.jpg",imgsrc);
//局部二值化
int blockSize = 15;
int constValue = 10;
cvAdaptiveThreshold(imgsrc, imgdst, 255, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY_INV, blockSize, constValue);
cvSaveImage("二值化.jpg",imgdst);
img_temp=imgdst;
cvErode(imgsrc,imgdst,NULL,corrode_index);//腐蚀图像
cvSaveImage("腐蚀结果.jpg", imgdst);
imgsrc = imgdst;
cvDilate(imgsrc,imgdst,NULL,1);//膨胀图像
cvSaveImage("膨胀结果.jpg", imgdst);
//不同类型图片处理函数不同
front(imgdst);
//back(imgdst,img_temp);
cvReleaseImage( &imgsrc );
return 0;
}