#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 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 CBinarization::Histogram( QImage* img ) { unsigned char* graydata = img->bits(); vector 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; }