#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<height *
src_image->width )<
//计算每个灰度级的像素数目占整幅图像的比例
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<
return
-1;
}
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;
}