#include"define.h" #include #include #include #include typedef struct { BYTE b; BYTE g; BYTE r; }RGB; int calculateOtsuThreshold(const std::vector& grayscaleImage) { int histogram[256] = { 0 }; int totalPixels = grayscaleImage.size(); for (int i = 0; i < totalPixels; ++i) { histogram[grayscaleImage[i]]++; } float maxVariance = 0.0f; int threshold = 0; for (int t = 0; t < 256; ++t) { int w0 = 0; int w1 = 0; int sum0 = 0; int sum1 = 0; for (int i = 0; i < 256; ++i) { if (i <= t) { w0 += histogram[i]; sum0 += i * histogram[i]; } else { w1 += histogram[i]; sum1 += i * histogram[i]; } } float mean0 = (w0 == 0) ? 0 : static_cast(sum0) / w0; float mean1 = (w1 == 0) ? 0 : static_cast(sum1) / w1; float variance = static_cast(w0 * w1) * pow(mean0 - mean1, 2); if (variance > maxVariance) { maxVariance = variance; threshold = t; } } return threshold; } bool otsu_binary(const void*image,int thresh){ auto imageptr=(uintptr_t)image; BITMAPFILEHEADER *fileHeader=(BITMAPFILEHEADER*)imageptr; imageptr+=sizeof(BITMAPFILEHEADER); BITMAPINFOHEADER *infoHeader=(BITMAPINFOHEADER*)imageptr; imageptr+=sizeof(BITMAPINFOHEADER); int height, weight; height = infoHeader->biHeight; weight = infoHeader->biWidth; if (infoHeader->biBitCount == 24) { int size = height * weight; RGB* img = (RGB*)imageptr; int threshold; if(thresh==-1){ std::vector grayscaleImage; for (int i = 0; i < size; i++) { grayscaleImage.push_back((BYTE)((img[i].r * 19595 + img[i].g * 38469 + img[i].b * 7472) >> 16)); } threshold = calculateOtsuThreshold(grayscaleImage); } else{ threshold=thresh; } for (int i = 0; i < size; i++) { if ((BYTE)((img[i].r * 19595 + img[i].g * 38469 + img[i].b * 7472) >> 16) > threshold) { img[i].r = img[i].g = img[i].b = 255; } else { img[i].r = img[i].g = img[i].b = 0; } } return true; } else{ return false; } }