灰度拉升-[opencv水位识别]部分知识点

灰度拉升-[opencv水位识别]部分知识点_第1张图片灰度拉升-[opencv水位识别]部分知识点_第2张图片

灰度拉升-[opencv水位识别]部分知识点_第3张图片

灰度拉升-[opencv水位识别]部分知识点_第4张图片

灰度拉升-[opencv水位识别]部分知识点_第5张图片

#include 
#include 
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(0);
	uchar* dstData = dst.ptr(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; i0.9)     //high_value取值接近于90%的总像素的灰度值
		{
			high_value = i;
			break;
		}
	}
	rate = (float)255 / (high_value - low_value + 1);
	//进行灰度拉伸
	for (i = 0; ihigh_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(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;
}

灰度拉升-[opencv水位识别]部分知识点_第6张图片

灰度拉升-[opencv水位识别]部分知识点_第7张图片

 

上述中代码有一个技术问题,那就是求最大值最小值

可以用opencv的函数

minMaxIdx(srcImg, &minVal, &maxVal/*, minIdx, maxIdx*/);  // 寻找图像的最大最小值

非常方便速度快

 

接着说算法,我们得效果没有文章中的好,不知道他是怎么做的

发现是自己的问题,上述代码并没有求出所有的参数,但我自己不知道参数怎么给定,发现新的确定参数的公式

灰度拉升-[opencv水位识别]部分知识点_第8张图片

 

参数很重要,所以,在原来得代码基础上,改一改参数

就可以了

灰度拉升-[opencv水位识别]部分知识点_第9张图片

    //计算两个阈值点的值
    for (i = 0; i<256; i++)
    {
        if (stretch_p1[i]<0.2)     //low_value取值接近于10%的总像素的灰度值
        {
            low_value = i;
        }
        if (stretch_p1[i]>0.98)     //high_value取值接近于90%的总像素的灰度值
        {
            high_value = i;
            break;
        }
    }

附上结果图:

灰度拉升-[opencv水位识别]部分知识点_第10张图片

和论文中的结果相差无几,ok!

你可能感兴趣的:(opencv)