142 lines
3.5 KiB
Plaintext
142 lines
3.5 KiB
Plaintext
#include "Binarization.h"
|
|
|
|
CBinarization::CBinarization( QString imgPath )
|
|
: threshold(0)
|
|
{
|
|
// 加载图片
|
|
_img = new QImage();
|
|
if (NULL != _img)
|
|
{
|
|
_img->load(imgPath);
|
|
}
|
|
}
|
|
|
|
// 生成灰度图像
|
|
QImage* CBinarization::grayScaleImg()
|
|
{
|
|
if (NULL == _img)
|
|
{
|
|
return NULL;
|
|
}
|
|
int nWidth = _img->width();
|
|
int nHeight = _img->height();
|
|
|
|
// 这里留意,我使用了QImage::Format_Grayscale8格式的图片,这种图片每个像素只用了8bit存储灰度颜色值
|
|
QImage* grayImg = new QImage(nWidth, nHeight, QImage::Format_RGB888);
|
|
QRgb rgbVal = 0;
|
|
int grayVal = 0;
|
|
|
|
for (int x = 0; x < nWidth; ++x)
|
|
{
|
|
for (int y = 0; y < nHeight; ++y)
|
|
{
|
|
rgbVal = _img->pixel(x, y);
|
|
|
|
grayVal = qGray(rgbVal); // 这里调用Qt的函数,使用(R * 11 + G * 16 + B * 5)/32的方法计算
|
|
|
|
grayImg->setPixel(x, y, QColor(grayVal, grayVal, grayVal).rgb());
|
|
}
|
|
}
|
|
|
|
return grayImg;
|
|
}
|
|
|
|
int CBinarization::Otsu(QImage* img)
|
|
{
|
|
if (NULL == img)
|
|
{
|
|
return -1;
|
|
}
|
|
vector<int> histogram = Histogram(img);
|
|
int total = 0;
|
|
for (int i = 0; i != histogram.size(); ++i)
|
|
{
|
|
total += histogram[i];
|
|
}
|
|
|
|
double sum = 0.0;
|
|
for (unsigned int i = 1; i < histogram.size(); ++i)
|
|
sum += i * histogram[i];
|
|
double sumB = 0.0;
|
|
double wB = 0.0;
|
|
double wF = 0.0;
|
|
double mB = 0.0;
|
|
double mF = 0.0;
|
|
double max = 0.0;
|
|
double between = 0.0;
|
|
double threshold = 0.0;
|
|
for (int i = 0; i != 256; ++i)
|
|
{
|
|
wB += histogram[i];
|
|
if (wB == 0)
|
|
continue;
|
|
wF = total - wB;
|
|
if (wF == 0)
|
|
break;
|
|
sumB += i * histogram[i];
|
|
mB = sumB / wB;
|
|
mF = (sum - sumB) / wF;
|
|
between = wB * wF * (mB - mF) * (mB - mF);
|
|
if ( between > max )
|
|
{
|
|
threshold = i;
|
|
max = between;
|
|
}
|
|
}
|
|
return threshold;
|
|
}
|
|
|
|
QImage* CBinarization::process(QImage* img)
|
|
{
|
|
if (NULL == img)
|
|
{
|
|
return NULL;
|
|
}
|
|
int width = img->width();
|
|
int height = img->height();
|
|
int bytePerLine = img->bytesPerLine(); // 每一行的字节数
|
|
unsigned char *data = img->bits();
|
|
unsigned char *binarydata = new unsigned char[bytePerLine * height];
|
|
|
|
unsigned char g = 0;
|
|
for (int i = 0; i < height; ++i)
|
|
{
|
|
for (int j = 0; j < width; ++j)
|
|
{
|
|
g = *(data + i * bytePerLine + j * 3); // 这里j 乘以 3
|
|
if(int(g) >= threshold)
|
|
{
|
|
binarydata[ i * bytePerLine + j * 3] = 0xFF; // 每个色值需要对3个字节赋值
|
|
binarydata[ i * bytePerLine + j * 3 + 1] = 0xFF;
|
|
binarydata[ i * bytePerLine + j * 3 + 2] = 0xFF;
|
|
}
|
|
else
|
|
{
|
|
binarydata[ i * bytePerLine + j * 3] = 0x00;
|
|
binarydata[ i * bytePerLine + j * 3 + 1] = 0x00;
|
|
binarydata[ i * bytePerLine + j * 3 + 2] = 0x00;
|
|
}
|
|
}
|
|
}
|
|
|
|
QImage *ret = new QImage(binarydata, width, height, bytePerLine, QImage::Format_RGB888);
|
|
return ret;
|
|
}
|
|
|
|
std::vector<int> CBinarization::Histogram( QImage* img )
|
|
{
|
|
unsigned char* graydata = img->bits();
|
|
vector<int> hist(256); // 256色
|
|
for (int i = 0; i != img->width(); ++i)
|
|
{
|
|
for (int j = 0; j != img->height(); ++j)
|
|
{
|
|
int index = int(*graydata);
|
|
hist[index] += 1;
|
|
graydata += 1; // step
|
|
}
|
|
}
|
|
graydata = NULL;
|
|
return hist;
|
|
}
|