See More

/* * @brief Ö±·½Í¼¾ùºâ»¯ * @author Îâ³ÛÓò 3140100333 * @date 2017-04-12 */ #include #include #include #include "image_io.h" using namespace std; #define BITMAP_ID 0x4D42 unsigned char* equalization(BITMAPFILEHEADER *bitmapFileHeader, BITMAPINFOHEADER *bitmapInfoHeader, unsigned char *bitmapData) { unsigned char* newbitmapData = new unsigned char[bitmapInfoHeader->biSizeImage]; int m = bitmapInfoHeader->biHeight; // **ÐÐÊý²»ÐèÒª³Ë3 int n = (bitmapInfoHeader->biWidth + 3) / 4 * 4 * 3; int *histogram_red = new int[256](); // nk int *histogram_green = new int[256](); int *histogram_blue = new int[256](); double *sk_red = new double[256](); // sk double *sk_green = new double[256](); double *sk_blue = new double[256](); int *skt_red = new int[256](); // ~sk int *skt_green = new int[256](); int *skt_blue = new int[256](); int *num_red = new int[256](); // new_nk int *num_green = new int[256](); int *num_blue = new int[256](); int size = bitmapInfoHeader->biWidth * bitmapInfoHeader->biHeight; // ÇóÖ±·½Í¼ for (int i = 0; i < m; i++) for (int j = 0; j < n; j += 3) { histogram_red[bitmapData[i*n + j + 2]] ++; histogram_green[bitmapData[i*n + j + 1]] ++; histogram_blue[bitmapData[i*n + j]] ++; } /* ²âÊÔ histogram_red[0] = 790;histogram_red[1] = 1023;histogram_red[2] = 850; histogram_red[3] = 656;histogram_red[4] = 329;histogram_red[5] = 245; histogram_red[6] = 122;histogram_red[7] = 81;size = 4096; */ // Çó³öskµÄ¸ÅÂÊ for (int i = 0; i < 256; i++) { if (i == 0) { sk_red[i] += histogram_red[i]; sk_green[i] += histogram_green[i]; sk_blue[i] += histogram_blue[i]; } else { sk_red[i] = sk_red[i - 1] + histogram_red[i]; sk_green[i] = sk_green[i - 1] + histogram_green[i]; sk_blue[i] = sk_blue[i - 1] + histogram_green[i]; sk_red[i - 1] /= size; sk_green[i - 1] /= size; sk_blue[i - 1] /= size; } } sk_red[255] = sk_green[255] = sk_blue[255] = 1.0; // ÇóÓësk×î½Ó½üµÄÏîskt(~s)ÒÔ¼°°Ñk¶ÔÓ¦µÄnkÖµÀÛ¼Óµ½sktÉÏ¡£sktµÃµ½µÄÊÇ×î½Ó½üµÄÏîµÄÐòºÅ£¬numµÃµ½µÄÊÇзÖÅäµÄnk int sum_red = 0, sum_green = 0, sum_blue = 0; for (int i = 0; i < 256; i++) { double min_red = 1.0, min_green = 1.0, min_blue = 1.0; // ºìÉ« for (int j = sum_red; j < 256; j++) { double tmp = sk_red[i] - j *1.0 / 255; // **³Ë1.0 if (tmp < 0) tmp = -tmp; if (min_red > tmp) { min_red = tmp; sum_red = j; } else break; } skt_red[i] = sum_red; num_red[sum_red] += histogram_red[i]; // ÂÌÉ« for (int j = sum_green; j < 256; j++) { double tmp = sk_green[i] - j *1.0 / 255; // **³Ë1.0 if (tmp < 0) tmp = -tmp; if (min_green > tmp) { min_green = tmp; sum_green = j; } else break; } skt_green[i] = sum_green; num_green[sum_green] += histogram_green[i]; // À¶É« for (int j = sum_blue; j < 256; j++) { double tmp = sk_blue[i] - j *1.0 / 255; // **³Ë1.0 if (tmp < 0) tmp = -tmp; if (min_blue > tmp) { min_blue = tmp; sum_blue = j; } else break; } skt_blue[i] = sum_blue; num_blue[sum_blue] += histogram_blue[i]; } /* Êä³ö²âÊÔ½á¹û printf("k: "); for (int i = 0; i < 8; i++) { printf("%d ", i); } printf("\nnk: "); for (int i = 0; i < 8; i++) { printf("%d ", histogram_red[i]); } printf("\nsk: "); for (int i = 0; i < 8; i++) { printf("%.2f ", sk_red[i]); } printf("\n~sk: "); for (int i = 0; i < 8; i++) { printf("%d ", skt_red[i]); } printf("\nnew_nk: "); int pre = -1; for (int i = 0; i < 8; i++) { if (skt_red[i] != pre) printf("%d ", num_red[skt_red[i]]); else printf(" "); pre = skt_red[i]; } printf("\n");*/ // ±éÀúËùÓÐÏñËØµã£¬¸ù¾ÝеÄÖ±·½Í¼¸³ÓèеÄÖµ for (int i = 0; i < m; i++) for (int j = 0; j < n; j += 3) { newbitmapData[i*n + j + 2] = skt_red[bitmapData[i*n + j + 2]]; newbitmapData[i*n + j + 1] = skt_green[bitmapData[i*n + j + 1]]; newbitmapData[i*n + j] = skt_blue[bitmapData[i*n + j]]; } return newbitmapData; } unsigned char* equalization_grey(BITMAPFILEHEADER *bitmapFileHeader, BITMAPINFOHEADER *bitmapInfoHeader, unsigned char *bitmapData) { unsigned char* newbitmapData = new unsigned char[bitmapInfoHeader->biSizeImage]; int m = bitmapInfoHeader->biHeight; // **ÐÐÊý²»ÐèÒª³Ë3 int n = (bitmapInfoHeader->biWidth + 3) / 4 * 4 * 3; int *histogram = new int[256](); // nk double *sk = new double[256](); // sk int *skt = new int[256](); // ~sk int *num = new int[256](); // new_nk int size = bitmapInfoHeader->biWidth * bitmapInfoHeader->biHeight; // ÇóÖ±·½Í¼ for (int i = 0; i < m; i++) for (int j = 0; j < n; j += 3) { double y = 0.3 * bitmapData[i*n + j + 2] + 0.59 * bitmapData[i*n + j + 1] + 0.11 * bitmapData[i*n + j]; histogram[(int)y] ++; } // Çó³öskµÄ¸ÅÂÊ for (int i = 0; i < 256; i++) { if (i == 0) { sk[i] += histogram[i]; } else { sk[i] = sk[i - 1] + histogram[i]; sk[i - 1] /= size; } } sk[255] = 1.0; // ÇóÓësk×î½Ó½üµÄÏîskt(~s)ÒÔ¼°°Ñk¶ÔÓ¦µÄnkÖµÀÛ¼Óµ½sktÉÏ¡£sktµÃµ½µÄÊÇ×î½Ó½üµÄÏîµÄÐòºÅ(»Ò¶Èͼ¼¶±ð)£¬¼´¶ÔÔ­¼¶±ðµ½Ð¼¶±ð×öÁËÒ»¸öÓ³É䣻numµÃµ½µÄÊÇзÖÅäµÄnk int sum = 0; for (int i = 0; i < 256; i++) { double min = 1.0; // ÕÒ×î½Ó½üµÄÏÀûÓÃÆäµ¥µ÷ÐÔÿ´Î¿ÉÒÔ´ÓÉϴεĽá¹ûsum¿ªÊ¼Ã¶¾Ù for (int j = sum; j < 256; j++) { double tmp = sk[i] - j *1.0 / 255; // **³Ë1.0 if (tmp < 0) tmp = -tmp; if (min > tmp) // ¼Ç¼×îСµÄ¾àÀëºÍ±êºÅ { min = tmp; sum = j; } else break; } skt[i] = sum; num[sum] += histogram[i]; // ΪзֵõĻҶȼ¶±ðÀÛ»ýÏñËØµã¸öÊý } // ±éÀúËùÓÐÏñËØµã£¬¸ù¾ÝеÄÖ±·½Í¼¸³ÓèеÄÖµ for (int i = 0; i < m; i++) for (int j = 0; j < n; j += 3) { // ¸ù¾ÝÔ­ÏñËØµãµÄ»Ò¶È¼¶±ðͨ¹ýsktת»»µ½Ðµļ¶±ð£¬ÔÙת»»»ØRGB¡£ double y = 0.3 * bitmapData[i*n + j + 2] + 0.59 * bitmapData[i*n + j + 1] + 0.11 * bitmapData[i*n + j]; double u = 0.493 * (bitmapData[i*n + j] - y); double v = 0.877 * (bitmapData[i*n + j + 2] - y); double tmp = skt[(int)y]; // ·ÀÖ¹Òç³ö£¬¿¼ÂÇÉÏÒçºÍÏÂÒç // À¶É«Í¨µÀ double color = u / 0.493 + tmp; if (color > 255) newbitmapData[i*n + j] = 255; else if (color < 0) newbitmapData[i*n + j] = 0; else newbitmapData[i*n + j] = color; // ºìɫͨµÀ color = v / 0.877 + tmp; if (color > 255) newbitmapData[i*n + j + 2] = 255; else if (color < 0) newbitmapData[i*n + j + 2] = 0; else newbitmapData[i*n + j + 2] = color; // ÂÌɫͨµÀ color = (tmp - 0.11 * bitmapData[i*n + j] - 0.3 * bitmapData[i*n + j + 2]) / 0.59; if (color > 255) newbitmapData[i*n + j + 1] = 255; else if (color < 0) newbitmapData[i*n + j + 1] = 0; else newbitmapData[i*n + j + 1] = color; } return newbitmapData; }