灰度拉昇-[opencv水位識別]部分知識點
阿新 • • 發佈:2018-12-15
#include <iostream> #include <opencv2/opencv.hpp> using namespace std; using namespace cv; void stretch(Mat &src, Mat &dst, int nMin, int nMax) { int low_value = nMin; //拉伸後像素的最小值 int high_value = nMax; //拉伸後像素的最大值 float rate = 0; //影象的拉伸率 float stretch_p[256], stretch_p1[256], stretch_num[256]; //清空三個陣列,初始化填充陣列元素為0 memset(stretch_p, 0, sizeof(stretch_p)); memset(stretch_p1, 0, sizeof(stretch_p1)); memset(stretch_num, 0, sizeof(stretch_num)); //統計影象各個灰度級出現的次數 uchar* srcData = src.ptr<uchar>(0); uchar* dstData = dst.ptr<uchar>(0); //相當於c語言版本opencv的: //uchar* srcData = (uchar*)src->imageData; //uchar* dstData = (uchar*)dst->imageData; int nHeight = src.rows; int nWidth = src.cols; int i, j; uchar nVal = 0; for (i = 0; i<nHeight; i++) { for (j = 0; j<nWidth; j++) { nVal = srcData[i*nWidth + j]; stretch_num[nVal]++; } } //統計各個灰度級出現的概率 for (i = 0; i<256; i++) { stretch_p[i] = stretch_num[i] / (nHeight*nWidth); } //統計各個灰度級的概率和 for (i = 0; i<256; i++) { for (j = 0; j <= i; j++) { stretch_p1[i] += stretch_p[j]; } } //計算兩個閾值點的值 for (i = 0; i<256; i++) { if (stretch_p1[i]<0.1) //low_value取值接近於10%的總畫素的灰度值 { low_value = i; } if (stretch_p1[i]>0.9) //high_value取值接近於90%的總畫素的灰度值 { high_value = i; break; } } rate = (float)255 / (high_value - low_value + 1); //進行灰度拉伸 for (i = 0; i<nHeight; i++) { for (j = 0; j<nWidth; j++) { nVal = srcData[i*nWidth + j]; if (nVal<low_value) { dstData[i*nWidth + j] = 0; } else if (nVal>high_value) { dstData[i*nWidth + j] = 255; } else { dstData[i*nWidth + j] = (uchar)((nVal - low_value)*rate + 0.5); if (dstData[i*nWidth + j]>255) { dstData[i*nWidth + j] = 255; } } } } } int main(int argc, char* argv[]) { Mat img = imread("11.bmp", 0); if (img.empty()) { cout << "Error: Could not load image" << endl; return 0; } imshow("img", img); Mat dst = img.clone(); //計算影象的最大最小值 最大值賦0,最小值賦255 int pixMax = 0, pixMin = 255; uchar * pdata = NULL; for (size_t r = 0; r < img.rows; r++) { pdata = img.ptr<uchar>(r); for (size_t c = 0; c < img.cols; c++) { if (pdata[c] > pixMax) pixMax = pdata[c]; if (pdata[c] < pixMin) pixMin = pdata[c]; } } stretch(img, dst, pixMin, pixMax); imshow("dst", dst); waitKey(); return 0; }
效果沒有文章中的好,不知道他是怎麼做的