前言
本文介绍使用OpenCV之调整图片亮度和对比度
理论
图像变换可以看作如下:
1)像素变换 – 点操作,用在调整图像亮度和对比度等操作上
2)邻域操作 – 区域,用在图像卷积、特征提取、梯度计算、模式匹配识别、角点检测、模糊、平滑等操作上
调整图像亮度和对比度属于像素变换 - 点操作
g(i,j) = αf(i,j) + β
两个参数α
和β
称作增益和偏置参数,用这两个参数来分别控制对比度和亮度
核心思路
1、将UIImage转换为C++图片
2、4通道转3通道
3、创建一张跟原图像大小和类型一致的空白图像dst = Mat::zeros(src.size(), src.type())
4、for循环绘制输出图saturate_cast(value)确保值大小范围为0~255之间
5、将c++图片转换为UIImage
代码演示
这里有一点需要注意的就是,需要将4通道图片转换为3通道,
/* 4通道转成3通道 */ NS_INLINE cv::Mat kFourChannelsBecomeThree(const cv::Mat src){ Mat dst; if (src.channels() == 4) { cv::cvtColor(src, dst, COLOR_RGBA2RGB); return dst; } return src; }
如果不转换的话,得到的图片显示不完全
/* 调整图片亮度和对比度,contrast[0-100],luminance[0-2] */ - (UIImage*)kj_opencvChangeContrast:(int)contrast luminance:(double)luminance{ cv::Mat src,dst; UIImageToMat(self,src,true); src = kFourChannelsBecomeThree(src); dst = Mat::zeros(src.size(), src.type()); int channels = src.channels(); for (int i = 0; i < src.rows; i++) { for (int j = 0; j < src.cols; j++) { if (channels == 3) {//rgb dst.at<Vec3b>(i, j)[0] = saturate_cast<uchar>(src.at<Vec3b>(i, j)[0] * luminance + contrast); dst.at<Vec3b>(i, j)[1] = saturate_cast<uchar>(src.at<Vec3b>(i, j)[1] * luminance + contrast); dst.at<Vec3b>(i, j)[2] = saturate_cast<uchar>(src.at<Vec3b>(i, j)[2] * luminance + contrast); }else if (channels == 1) {//gray dst.at<uchar>(i, j) = saturate_cast<uchar>(src.at<uchar>(i, j) * luminance + contrast); } } } return kMatToUIImage(dst); }
效果图
上图为原图
系列文章关联
接下来我会慢慢补充Opencv的相关文章,暂时已将常见的图片处理和图片算法封装出来,有需要的朋友可以去pod 'OpencvQueen'