OpenCV-1.7 图像对比度和亮度调整

目标

本教程包含如下学习内容

  • 获取像素值
  • 初始化一个像素矩阵
  • 学习cv::saturate_cast用法以及应用
  • 学习有关像素转换的炫酷的信息
  • 通过一个例子进行图像的亮度增强

理论

注 : \color{#1Ff0f0}{注:} :
  下述内容引用自书籍Computer Vision: Algorithms and Applications。

图像处理
  • 通常一个图像操作代表将一个或多个输入图像进行一个函数处理后得到输出图像的过程。
  • 图像转换包括:
    • 像素点操作
    • 邻域操作
像素点操作
  • 在这类图像转换处理中,每一个输出像素值仅仅取决于对应的输入像素值(或者是一些全局搜集的参数和信息)。
  • 比如亮度调整,对比度调整和颜色修正与转换。
亮度和对比度调整
  • 两种常用的像素点处理是乘法和加法:
    在这里插入图片描述
  • 参数α>0 和β 通常被称之为增益与偏置参数。
  • 我们可以理解成f(x)作为输出图像的像素,g(x)为输出图像像素。因此上述公式可以简单表达为:
    在这里插入图片描述
    ij 分代表第 i 行和第 j

代码

public class Main {
    private static byte saturate(double val) {
        int iVal = (int) Math.round(val);
        iVal = iVal > 255 ? 255 : (iVal < 0 ? 0 : iVal);
        return (byte) iVal;
    }
    public static void main(String[] args) {
        System.loadLibrary("libs/"+ Core.NATIVE_LIBRARY_NAME);
        String filename = "images/lena.jpg";
        Mat img = imread(filename);
        Mat dst = Mat.zeros(img.size(),img.type());
        double alpha = 2.0;
        int beta = -125;
        byte[] imageData =new byte[(int) (img.total()*img.channels())];
        img.get(0,0,imageData);
        byte[] newImageData = new byte[(int) (dst.total() * dst.channels())];
        for (int y = 0; y < img.rows(); y++) {
            for (int x = 0; x < img.cols(); x++) {
                for (int c = 0; c < img.channels(); c++) {
                    double pixelValue = imageData[(y*img.cols()+x)*img.channels()+c];
                    pixelValue = pixelValue<0?pixelValue+256:pixelValue;
                    newImageData[(y*img.cols()+x)*img.channels()+c] = saturate(alpha*pixelValue+beta);
                }
            }
        }
        dst.put(0,0,newImageData);
        imshow("raw image",img);
        imshow("new image",dst);
        waitKey();
        System.exit(0);
    }
}

讲解

  • 首先我们用imread方法载入图像
        String filename = "images/lena.jpg";
        Mat img = imread(filename);
  • 下一步,我们需要对载入的图像进行处理转换,并且将转换结果存储到一个新的Mat对象中,我们希望新的Mat对象拥有如下特性:
    • 初始化所有像素值为0
    • 与原图像拥有相同的大小
 		Mat dst = Mat.zeros(img.size(),img.type());
  • 接下来我们通过Mat::get 方法将图像中像素取出到byte数组,并且利用三个for循环对每一行每一列以及每个颜色通道(B G R)进行遍历,对每个像素进行操作saturate(alpha * pixelValue + beta);
        byte[] imageData =new byte[(int) (img.total()*img.channels())];
        img.get(0,0,imageData);
        byte[] newImageData = new byte[(int) (dst.total() * dst.channels())];
        for (int y = 0; y < img.rows(); y++) {
            for (int x = 0; x < img.cols(); x++) {
                for (int c = 0; c < img.channels(); c++) {
                    double pixelValue = imageData[(y*img.cols()+x)*img.channels()+c];
                    pixelValue = pixelValue<0?pixelValue+256:pixelValue;
                    newImageData[(y*img.cols()+x)*img.channels()+c] = saturate(alpha*pixelValue+beta);
                }
            }
        }
        dst.put(0,0,newImageData);

注 : \color{#1Ff0f0}{注:} :
  上述代码采用了三层的for循环,其实我们可以通过下面代码简单实现同样功能:
img.convertTo(dst, -1, alpha, beta);

cv::Mat::convertTo 方法针对new_image = aimage + beta*.的操作相当高效,我们主要是为了演示如何获取以及修改每个像素才使用如上的循环。

结果

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值