基于MFC的图像局部二值化处理方法
本文介绍一种基于MFC的图像处理方法,主要针对BMP格式图像的局部二值化处理。通过分析图像数据结构,结合滑动窗口技术实现不同区域的自适应二值化。
首先我们读取并解析BMP图像文件头信息:
BITMAPFILEHEADER hdr;
BITMAPINFOHEADER bmpInfo;
memcpy(&hdr, pData, 14);
memcpy(&bmpInfo, pData + 14, 40);
int width = bmpInfo.biWidth;
int height = bmpInfo.biHeight;
int bitCount = bmpInfo.biBitCount;
接下来我们实现全局二值化处理:
unsigned char* processGlobalBinary(unsigned char* data, int width, int height, int bitCount) {
unsigned char* result = new unsigned char[width * height * 3];
int bytesPerLine = ((width * bitCount + 31) >> 5) << 2;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int index = y * bytesPerLine + x * 3;
int r = data[index];
int g = data[index + 1];
int b = data[index + 2];
int gray = (r * 19595 + g * 38469 + b * 7472) >> 16;
int threshold = 80;
if (gray > threshold) {
result[index] = result[index + 1] = result[index + 2] = 255;
} else {
result[index] = result[index + 1] = result[index + 2] = 0;
}
}
}
return result;
}
进一步我们实现基于滑动窗口的局部二值化:
unsigned char* processLocalBinary(unsigned char* data, int width, int height, int bitCount) {
unsigned char* result = new unsigned char[width * height * 3];
int bytesPerLine = ((width * bitCount + 31) >> 5) << 2;
for (int y = 4; y < height - 4; y++) {
for (int x = 12; x < width - 12; x += 3) {
int index = y * bytesPerLine + x * 3;
int r = data[index];
int g = data[index + 1];
int b = data[index + 2];
int gray = (r * 19595 + g * 38469 + b * 7472) >> 16;
int sum = 0;
for (int m = y - 4; m < y + 4; m++) {
for (int n = x - 12; n < x + 12; n += 3) {
int mIndex = m * bytesPerLine + n;
sum += data[mIndex];
}
}
int threshold = (int)(sum * 1.23 / 81);
if (gray > threshold) {
result[index] = result[index + 1] = result[index + 2] = 255;
} else {
result[index] = result[index + 1] = result[index + 2] = 0;
}
}
}
return result;
}
通过实验发现:
- 全局二值化在处理复杂光照条件时效果欠佳
- 滑动窗口大小对边缘检测效果有显著影响
- 阈值计算方法对最终效果有重要影响