OpenCV灰度值线性变换与分段线性变换

来源:互联网 发布:淘宝图片转码 编辑:程序博客网 时间:2024/05/08 10:25

1.公式


1.1线性变换

假设原图像 f(x,y)的灰度范围为[a,b],希望变换后图像 g(x,y)的灰度范围扩展至[c,d],则灰度线性变换可表示为

1.2分段线性变换



2.C++代码实现

#include "cv.h"                         #include "highgui.h"#include "cvaux.h"#include "cxcore.h"#include "opencv2/opencv.hpp"#include "opencv2/imgproc.hpp"#include <iostream>#include <string>using namespace cv;using namespace std;Mat image;//原图像Mat target1;//输出图像Mat target2;//原始图像灰度范围[a,b]int a = 255;int b = 0;//灰度线性变换,前提是传入的图像是灰度图void toGray(Mat src, float c, float d){    target1 = Mat::zeros(src.size(), src.type());    for (int i = 0; i < src.rows; i++)    {        for (int j = 0; j < src.cols; j++)        {            //线性变换,saturate_cast作用是防止数组越界            target1.at<uchar>(i, j) = saturate_cast<uchar>(( d-c)/(b-a) * (src.at<uchar>(i, j) -a ) + c);        }    }}//灰度分段线性变换(这里有个小疑惑,可能写错了,我没有按照公式来写)void piecewiseToGray(Mat src, float c, int d){    target2 = Mat::zeros(src.size(), src.type());    for (int i = 0; i < src.rows; i++)    {        for (int j = 0; j < src.cols; j++)        {            if(target2.at<uchar>(i, j) < c)                target2.at<uchar>(i, j) = saturate_cast<uchar>( (c/a) * src.at<uchar>(i, j) );            else if(c < target2.at<uchar>(i, j) && target2.at<uchar>(i, j) < d )                target2.at<uchar>(i, j) = saturate_cast<uchar>((d - c) / (b - a) * (src.at<uchar>(i, j) - a) + c);            else                target2.at<uchar>(i, j) = saturate_cast<uchar>((255-d) / (255-b) * (src.at<uchar>(i, j) - b) + d);        }    }}//获取原图像灰度范围void getGrayValue(Mat src){    int value = 0;    for (int i = 0; i < src.rows; i++)    {        for (int j = 0; j < src.cols; j++)        {            value =  (int)src.at<uchar>(i, j);            if (value > b)                b = value;            if (value < a)                a = value;        }    }}int main(){    //加上0表示读入灰度图    image = imread("D:/opencv/testPic/d1.bmp",0);    if (image.empty())    {        printf("could not load pic!\n");        return -1;    }    namedWindow("src");    imshow("src", image);    //获得原图像灰度范围    getGrayValue(image);    //输入目标图像灰度范围    int c = 50;    int d = 150;    //根据目标图像灰度范围生成目标图像    toGray(image, c, d);    piecewiseToGray(image, c, d);    //Mat target = 255 - src; //相当于a=-1,b=255,OpenCV中有对Mat的运算符重载,可以直接Mat r = 255 - img或者~img来实现    namedWindow("target1", WINDOW_AUTOSIZE);     namedWindow("target2", WINDOW_AUTOSIZE);    imshow("target1", target1);      imshow("target2", target2);    imwrite("D:/opencv/testPic/d2.bmp",target1);    imwrite("D:/opencv/testPic/d3.bmp", target2);    waitKey(0);    return 0;}
原创粉丝点击