怎样用c语言对bmp图像进行线性拉伸

如题所述

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
 
using namespace std;
using namespace cv;
 
 
Mat XianChange(Mat &img, double alt, int base)//灰度线性变化、
{
CV_Assert(img.depth() != sizeof(uchar));  //声明只对深度8bit的图像操作  
Mat temp = img.clone();
 
int channels = img.channels();            //获取图像channel  
int nrows = img.rows;                     //矩阵的行数  
int ncols = img.cols*channels;             //矩阵的总列数=列数*channel分量数  
if (img.isContinuous())               //判断矩阵是否连续,若连续,我们相当于只需要遍历一个一维数组  
{
ncols *= nrows;
nrows = 1;                 //一维数组  
}
//遍历像素点灰度值  
for (int i = 0; i<nrows; i++)
{
uchar *p = temp.ptr<uchar>(i);    //获取行地址  
for (int j = 0; j<ncols; j++)
{
p[j] = alt*p[j] + base;//修改灰度值  
 
if (p[j] > 255)
p[j] = 255;
if (p[j] < 0)
p[j] = 0;
}
}
return temp;
}
 
Mat XianStretch(Mat &img, int a, int b, int c, int d)//线性灰度拉伸,将[a,b]拉伸到[c,d]
{
CV_Assert(img.depth() != sizeof(uchar));  //声明只对深度8bit的图像操作  
Mat temp = img.clone();
 
int channels = img.channels();            //获取图像channel  
int nrows = img.rows;                     //矩阵的行数  
int ncols = img.cols*channels;             //矩阵的总列数=列数*channel分量数  
if (img.isContinuous())               //判断矩阵是否连续,若连续,我们相当于只需要遍历一个一维数组  
{
ncols *= nrows;
nrows = 1;                 //一维数组  
}
//遍历像素点灰度值  
for (int i = 0; i<nrows; i++)
{
uchar *p = temp.ptr<uchar>(i);    //获取行地址  
for (int j = 0; j<ncols; j++)
{
if (p[j] < a)
p[j] = c / b * p[j];
else if (p[j] > a && p[j] < b)
p[j] = (d - c) / (b - a) * (p[j] - a) + c;
else
p[j] = (255 - d) / (255 - b) *(p[j] - b) + d;
}
}
return temp;
}
 
Mat HistogramEqu(Mat &img)               //直方均衡
{
CV_Assert(img.depth() != sizeof(uchar));  //声明只对深度8bit的图像操作  
Mat temp = img.clone();
int grayNum[260] = { 0 };
int grayMap[260] = { 0 };
 
int channels = img.channels();            //获取图像channel  
int nrows = img.rows;                     //矩阵的行数  
int ncols = img.cols*channels;             //矩阵的总列数=列数*channel分量数  
int allPixel = nrows*ncols;               //图像的像素总数
int c;                                    //用于计算累积分布概率
 
if (img.isContinuous())               //判断矩阵是否连续,若连续,我们相当于只需要遍历一个一维数组  
{
ncols *= nrows;
nrows = 1;    //一维数组  
}
//遍历像素点灰度值  
for (int i = 0; i<nrows; i++)
{
uchar *p = temp.ptr<uchar>(i);    //获取行地址  
for (int j = 0; j<ncols; j++)
{
grayNum[p[j]]++;        //原图像的直方图
}
}
 
for (int i = 0; i < 256; i++)     //重新定义新的直方图
{
c = 0;
for (int j = 0; j<=i; j++)
{
c += grayNum[j];
grayMap[i] = int (255 * c / allPixel);

}
//printf("%d %d\n", i, grayMap[i]);
}
 
 
 
for (int i = 0; i < nrows; i++)     //重新定义新的直方图
{
uchar *p = temp.ptr<uchar>(i);    //获取行地址  
for (int j = 0; j < ncols; j++)
{
p[j] = grayMap[p[j]];
}
}
return temp;
}
 
int main()
{
string picName = "lena256.jpg";
Mat A = imread(picName, CV_LOAD_IMAGE_GRAYSCALE);    //读入灰度图像  

imshow("变换前", A);
 
Mat B = XianChange(A, 1, 20);//根据需要设置不同的参数
imshow("线性变换后", B);
 
Mat C = XianStretch(A, 10, 100, 20, 50);//根据需要设置不同的参数
imshow("线性拉伸后", C);
 
Mat D = HistogramEqu(A);
imshow("直方均衡后", D);
 
waitKey();
return 0;
}

温馨提示:答案为网友推荐,仅供参考
相似回答