An excellent image traversal algorithm (using linear stretching of images as an example)

Reprinted from: http://blog.sina.com.cn/s/blog_794d61e80102w3zb.html

Key code block:

int data_max = 0,data_min = 255;//预设灰度值
int nl = image.rows;    //计算图像的行数
int nc = image.cols * image.channels();//计算图像的列数*通道数[注释1]
if(image.isContinuous())  //判断图像在内存中是否连续存储[注释2]
{
    
    
nc = nc * nl;
nl = 1;
}

int i,j;
uchar *data;   //定义访问指针
for(j = 0; j < nl; j ++)
{
    
    
	data = image.ptr<uchar>(j);//指针指向image的第j行,image如果连续存储,j=1
	for(i = 0; i < nc; i ++)
	{
    
    
		if(data[i] > data_max)        data_max = data[i];
	if(data[i] < data_min)        data_min = data[i];
	}
}
注释1:图像是一个二维矩阵,按照行列访问,如果是彩色三通道的图像,则可以看作类似魔方的三位矩阵,
还是按照行列访问,但是每一列会有三个通道数的像素值BGR。
此处把通道数算进去列数里面,就可以每个像素的三个通道都遍历赋值,把三维矩阵看作二维矩阵。

注释2:当图像在内存中是连续储存的,则可以把行列数归并,
把二维矩阵nl行*nc列看作一维矩阵1*(nl*nc)列。

Actual complete C++ code:

C/C++ Demo: 把灰度级由其原范围线性地拉伸至整个灰度级范围。

//通用
#include <iostream>
#include <stdio.h>
//图像操作
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

using namespace :: std;
using namespace :: cv;

int main()
{
    
    
//图像读取
Mat image = imread("Fig0310.tif");
//判断图像读取是否有问题
if(!image.data)
{
    
    
cout << "image read is error!" << endl;
return 0;
}
//图像基本信息输出
cout << "image Info:Height:" << image.size().height << " Width:" << image.size().width << endl;

//原始图像显示
namedWindow("Original Image");
imshow("Original Image", image);
imwrite("original.jpg", image);

//处理图像
int data_max = 0,data_min = 255;
int nl = image.rows;
int nc = image.cols * image.channels();
if(image.isContinuous())
{
    
    
nc = nc * nl;
nl = 1;
}

int i,j;
uchar *data;
for(j = 0; j < nl; j ++)
{
    
    
	data = image.ptr<uchar>(j);
	for(i = 0; i < nc; i ++)
	{
    
    
		if(data[i] > data_max)        data_max = data[i];
	if(data[i] < data_min)        data_min = data[i];
	}
}

cout << "data_max:" << data_max << " data_min:" << data_min << endl;

int temp = data_max - data_min;
for(j = 0; j < nl; j ++)
{
    
    
	data = image.ptr<uchar>(j);
	for(i = 0; i < nc; i ++)
	{
    
    
		data[i] = (data[i] - data_min) * 255 / temp;
	}
}
//显示图像
namedWindow("Process Image");
imshow("Process Image", image);
//保存图像
imwrite("result.JPG", image);

waitKey(0);
return 0;

}

Guess you like

Origin blog.csdn.net/weixin_44650358/article/details/115193998