opencv直方圖拉伸
阿新 • • 發佈:2017-08-19
histsize ext ++ etc ipp str opencv style 查找表
結果:
1、首先計算出一幅圖像的直方圖
//計算直方圖 cv::MatND ImageHist::getHist(const cv::Mat &image){ cv::Mat im; if(image.channels() == 3) cv::cvtColor(image,im,CV_RGB2GRAY,0); else im = image; float r[2]; r[0] = 0; r[1] = 255; const float *ranges[1]; ranges[0] = r; cv::calcHist(&im, 1, &channels, cv::Mat(), hist, 1, &histSize, ranges); return hist; } //將直方圖生成圖像,以便在MFC空間中顯示 cv::Mat ImageHist::getHistImage(const cv::Mat &image){ double maxVal = 0; double minVal = 0; cv::minMaxLoc(hist,&minVal,&maxVal,0,0); cv::Mat histImg(histSize,histSize,CV_8U,cv::Scalar(255)); int high = histSize * 0.9; for (int i = 0;i < histSize;++i) { float binVal = hist.at<float>(i); int inted = binVal / maxVal *high; cv::line(histImg, cv::Point(i,histSize), cv::Point(i,histSize - inted), cv::Scalar::all(0)); } return histImg; }
2、去掉直方圖兩端bin為0或者小於某一數量的bin並記錄去掉後兩端的灰度值(mini,maxi),然後利用以下公式對顏色查找表進行拉伸:
(i - mini) * 255 / (maxi - mini) + 0.5cv::Mat ImageHist::stretch(const cv::Mat &image,int minValue /* = 0 */){ int mini = 0; for (;mini < histSize;++mini) { if(hist.at<float>(mini) > minValue) break; } int maxi = histSize - 1; for (;maxi >= 0;--maxi) { if(hist.at<float>(maxi) > minValue) break; } cv::Mat lookup(1,256,CV_8U); for (int i = 0;i < histSize;++i) { if(i < mini) lookup.at<uchar>(i) = 0; else if(i > maxi) lookup.at<uchar>(i) = 255; else lookup.at<uchar>(i) =static_cast<uchar>((i - mini) * 255 / (maxi - mini) + 0.5); } cv::Mat result; cv::LUT(image,lookup,result); return result; }
結果:
opencv直方圖拉伸