1.概念
1.1全局二值化
根据自定义阀值对图像进行二值化处理,即灰度值大于阀值时设改像素灰度值为255,灰度值小于阈值时设该像素灰度值为0
1.2局部二值化
在局部范围内根据特定算法算出局部的阀值,这个局部的大小可以自己决定(例8*8),算法也可以自己觉得,本文所用的用法是局部平局的灰度值作为阀值。得到局部阀值再进行局部二值化处理
2.局部二值化结果
3.完整代码
#include "cv.h"
#include "highgui.h"
#include "cvaux.h"
#include "cxcore.h"
#include "opencv2/opencv.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
#include <string>
using namespace cv;
using namespace std;
Mat image3;
Mat target3;
//全局阈值二值化
void globalTwoValue(Mat src,int value)
{
target3 = Mat::zeros(src.size(), src.type());
for (int i = 0; i < src.rows; i++)
{
for (int j = 0; j < src.cols; j++)
{
break;
if (value > (int)src.at<uchar>(i, j))
target3.at<uchar>(i, j) = 0;
else
target3.at<uchar>(i, j) = 255;
}
}
}
//8*8局部二值化,阈值=局部平均灰度值
void localTwoValue(Mat src)
{
//1.先算出一列有几个8,剩下几个像素
int countRow = src.rows / 8;
int rowLeft = src.rows % 8;
//2.算出一列有几个8,剩下几个像素
int countCol = src.cols / 8;
int colLeft = src.cols % 8;
target3 = Mat::zeros(src.size(), src.type());
for (int k = 0; k < countRow; k++)
{
for (int l = 0; l < countCol; l++)
{
int value = 0;
for (int i = k * 8; i < (k + 1) * 8; i++)
{
for (int j = l * 8; j < (l + 1) * 8; j++)
{
value += (int)src.at<uchar>(i, j);
}
}
value = value / 64;
for (int i = k*8; i < (k + 1) * 8; i++)
{
for (int j = l * 8; j < (l + 1) * 8; j++)
{
if ((int)src.at<uchar>(i, j) < value )
target3.at<uchar>(i, j) = 0;
else
target3.at<uchar>(i, j) = 255;
}
}
}
}
//底部不足8*8部分
if (rowLeft != 0)
{
for (int k = countRow; k < countRow + rowLeft; k++)
{
for (int l = 0; l < countCol; l++)
{
int value = 0;
for (int i = countRow * 8; i < countRow * 8 + rowLeft; i++)
{
for (int j = l * 8; j < (l + 1) * 8; j++)
{
value += (int)src.at<uchar>(i, j);
}
}
value = value / (8 * rowLeft);
for (int i = countRow * 8; i < countRow * 8 + rowLeft; i++)
{
for (int j = l * 8; j < (l + 1) * 8; j++)
{
if ((int)src.at<uchar>(i, j) < value)
target3.at<uchar>(i, j) = 0;
else
target3.at<uchar>(i, j) = 255;
}
}
}
}
}
//右侧不足8*8部分
if (colLeft != 0)
{
for (int k = 0; k < countRow; k++)
{
for (int l = countCol; l < countCol + colLeft; l++)
{
int value = 0;
for (int i = k * 8; i < (k + 1) * 8; i++)
{
for (int j = countCol * 8; j < countCol * 8 + colLeft; j++)
{
value += (int)src.at<uchar>(i, j);
}
}
value = value / (8 * colLeft);
for (int i = k * 8; i < (k + 1) * 8; i++)
{
for (int j = countCol * 8; j < countCol * 8 + colLeft; j++)
{
if ((int)src.at<uchar>(i, j) < value)
target3.at<uchar>(i, j) = 0;
else
target3.at<uchar>(i, j) = 255;
}
}
}
}
}
//右下角 rowleft * colleft 部分
if (rowLeft != 0 && colLeft != 0)
{
int value = 0;
for (int i = 8 * countRow; i < src.rows; i++)
{
for (int j = 8 * countCol; j < src.cols; j++)
{
value += (int)src.at<uchar>(i, j);
}
}
value = value / (rowLeft * colLeft);
for (int i = 8 * countRow; i < src.rows; i++)
{
for (int j = 8 * countCol; j < src.cols; j++)
{
if ((int)src.at<uchar>(i, j) < value)
target3.at<uchar>(i, j) = 0;
else
target3.at<uchar>(i, j) = 255;
}
}
}
}
int main()
{
//加上0表示读入灰度图
image3 = imread("D:/opencv/testPic/d1.bmp", 0);
if (image3.empty())
{
printf("could not load pic!\n");
return -1;
}
namedWindow("image3");
imshow("image3", image3);
localTwoValue(image3);
namedWindow("target3");
imshow("target3", target3);
imwrite("D:/opencv/testPic/d4.bmp", target3);
waitKey(0);
return 0;
}