影象演算法之區域性直方圖均衡化(灰度影象)
阿新 • • 發佈:2020-12-31
技術標籤:工作隨筆篇VC++(影象處理篇)
1、函式定義
//區域性直方圖均衡化 ksize - 領域大小,kstep - 領域中心步長
struct stPGMImage* LocalEqualHist(struct stPGMImage* image, int ksize = 3, int kstep = 1);
2、函式實現
#include <math.h> #include <vector> using namespace std; struct stPGMImage* LocalEqualHist(struct stPGMImage* image_src, int ksize, int kstep) { struct stPGMImage* result = (struct stPGMImage*)malloc(sizeof(struct stPGMImage)); result->height = image_src->height; result->width = image_src->width; result->maxraw = image_src->maxraw; result->type = image_src->type; result->data = (unsigned char*)malloc(sizeof(unsigned char) * result->width * result->height); memcpy(result->data, image_src->data, image_src->height * image_src->width); int gray[256] = { 0 }; double gray_prob[256] = { 0 }; vector<unsigned char> indexs_hist; if (image_src->height < ksize || image_src->width < ksize || kstep <= 0) return NULL; double* pOutTemp = new double[image_src->height * image_src->width]{}; int* pDataRef = new int[image_src->height * image_src->width]{}; for (int yy = ksize / 2; yy < image_src->height - ksize / 2; yy += kstep) { unsigned char* pIn = (unsigned char*)(image_src->data + yy * image_src->width); for (int xx = ksize / 2; xx < image_src->width - ksize / 2; xx += kstep) { unsigned char vaule = pIn[xx]; indexs_hist.push_back(vaule); for (int y = yy - ksize / 2; y <= yy + ksize / 2; y++) { pIn = (unsigned char*)(image_src->data + y * image_src->width); for (int x = xx - ksize / 2; x <= xx + ksize / 2; x++) { vaule = pIn[x]; int size = indexs_hist.size(); if (vaule == indexs_hist[size - 1] || vaule == indexs_hist[0]) ; else if (vaule > indexs_hist[size - 1]) indexs_hist.push_back(vaule); else if (vaule < indexs_hist[0]) indexs_hist.insert(begin(indexs_hist), vaule); else { for (int i = 1; i < size; i++) { if (vaule == indexs_hist[i]) break; else if (vaule < indexs_hist[i] && vaule > indexs_hist[i - 1]) { indexs_hist.insert(begin(indexs_hist) + i, vaule); break; } } } gray[vaule]++; } } for (int i = 0; i < (int)indexs_hist.size(); i++) { for (int j = 0; j <= i; j++) gray_prob[indexs_hist[i]] += (double)(256 - 1) / (ksize * ksize) * gray[indexs_hist[j]]; } for (int y = yy - ksize / 2; y <= yy + ksize / 2; y++) { pIn = (unsigned char*)(image_src->data + y * image_src->width); for (int x = xx - ksize / 2; x <= xx + ksize / 2; x++) { pOutTemp[y * image_src->width + x] += gray_prob[pIn[x]]; pDataRef[y * image_src->width + x]++; } } for (unsigned char& m : indexs_hist) { gray[m] = 0; gray_prob[m] = 0; } indexs_hist.clear(); } } for (int y = 0; y < image_src->height; y++) { unsigned char* pOut = (unsigned char*)(result->data + y * result->width); unsigned char* pIn = (unsigned char*)(image_src->data + y * image_src->width); for (int x = 0; x < image_src->width; x++) { if (pDataRef[y * image_src->width + x] != 0) pOut[x] = trunc(pOutTemp[y * image_src->width + x] / pDataRef[y * image_src->width + x] + 0.5); else pOut[x] = pIn[x]; } } delete[] pOutTemp; delete[] pDataRef; return result; }