使用OpenCV处理图片的亮度、对比度、曝光、高光、阴影、饱和度、色温,色相(附源码) 您所在的位置:网站首页 高光阴影怎么画图片 使用OpenCV处理图片的亮度、对比度、曝光、高光、阴影、饱和度、色温,色相(附源码)

使用OpenCV处理图片的亮度、对比度、曝光、高光、阴影、饱和度、色温,色相(附源码)

2024-06-02 07:24| 来源: 网络整理| 查看: 265

集成opencv的方式请参照上一个帖子 OpenCV在iOS端的集成及Mat和UIImage互相转化(附源码)

废话不多说直接上代码,伸手党福利: 代码中记得引入头文件及命名空间

#import #import "CVTools.h" //对应的.h文件 命名空间在自己的.h文件后定义 using namespace cv; using namespace std;

下面的处理方法统一对使用最多的8bit图片处理,如果是16bit的图片需要修改对应的格式,在使用的方法内需要改动的如下: 255 调整为 65535 Vec4b 调整为 Vec4w uchar 调整为 ushort UCHAR_MAX 调整为 USHRT_MAX

1.亮度 //调整亮度 +(UIImage *)brightInPutImage:(UIImage *)inputImage value:(float)beta{ Mat g_srcImage = [CVTools cvMatFromUIImage:inputImage]; if(g_srcImage.empty()){ return nil; } Mat g_dstImage=Mat::zeros(g_srcImage.size(),g_srcImage.type()); g_srcImage.convertTo(g_dstImage, -1, 1, beta); return [CVTools UIImageFromCVMat:g_dstImage]; } 2.对比度 //调整对比度 +(UIImage *)contrasInPutImage:(UIImage *)inputImage value:(CGFloat)alpha{ Mat g_srcImage = [CVTools cvMatFromUIImage:inputImage]; if(g_srcImage.empty()){ return nil; } Mat g_dstImage=Mat::zeros(g_srcImage.size(),g_srcImage.type()); g_srcImage.convertTo(g_dstImage, -1, alpha, 1); return [CVTools UIImageFromCVMat:g_dstImage]; } 3.曝光

曝光调节的方法是是对伽马参数进行调节来啊达到调整曝光的目的

//调节曝光 +(UIImage *)gammaInPutImage:(UIImage *)inputImage value:(CGFloat)value{ Mat g_srcImage = [CVTools cvMatFromUIImage:inputImage]; double gamma_c = 1; double gamma_g = value; int height=g_srcImage.rows; int width=g_srcImage.cols; double val; Mat g_dstImage=Mat::zeros(g_srcImage.size(),g_srcImage.type()); for (int row=0; row 1.0f)temp = 1.0f; if (temp < 0.0f) temp = 0.0f; uchar utemp = uchar(UCHAR_MAX*temp); result.at(i,j)[k] = utemp; } result.at(i,j)[3] = input.at(i,j)[3]; } } return [CVTools UIImageFromCVMat:result]; } 5.阴影 // 调节阴影 /// - Parameters: /// - inputImage: inputImage /// - value: value +(UIImage *)shadowInPutImage:(UIImage *)inputImage value:(CGFloat)light{ Mat input = [CVTools cvMatFromUIImage:inputImage]; // 生成灰度图 cv::Mat gray = cv::Mat::zeros(input.size(), CV_32FC1); cv::Mat f = input.clone(); f.convertTo(f, CV_32FC3); vector pics; split(f, pics); gray = 0.299f*pics[2] + 0.587*pics[2] + 0.114*pics[0]; gray = gray / 255.0; // 确定阴影区 cv::Mat thresh = cv::Mat::zeros(gray.size(), gray.type()); thresh = (1.0f - gray).mul(1.0f - gray); // 取平均值作为阈值 Scalar t = mean(thresh); cv::Mat mask = cv::Mat::zeros(gray.size(), CV_16UC1); mask.setTo(35535, thresh >= t[0]); // 参数设置 int max = 4; float bright = light / 100.0f / max; float mid = 1.0f + max * bright; // 边缘平滑过渡 cv::Mat midrate = cv::Mat::zeros(input.size(), CV_32FC1); cv::Mat brightrate = cv::Mat::zeros(input.size(), CV_32FC1); for (int i = 0; i < input.rows; ++i) { uchar *m = mask.ptr(i); float *th = thresh.ptr(i); float *mi = midrate.ptr(i); float *br = brightrate.ptr(i); for (int j = 0; j < input.cols; ++j) { if (m[j] == 255.0) { mi[j] = mid; br[j] = bright; } else { mi[j] = (mid - 1.0f) / t[0] * th[j]+ 1.0f; br[j] = (1.0f / t[0] * th[j])*bright; } } } // 阴影提亮,获取结果图 cv::Mat result = cv::Mat::zeros(input.size(), input.type()); for (int i = 0; i < input.rows; ++i) { float *mi = midrate.ptr(i); float *br = brightrate.ptr(i); for (int j = 0; j < input.cols; ++j) { for (int k = 0; k < 3; ++k) { float temp = pow(float(input.at(i,j)[k]) / UCHAR_MAX, 1.0f / mi[j])*(1.0 / (1 - br[j])); if (temp > 1.0f) temp = 1.0f; if (temp < 0.0f) temp = 0.0f; uchar utemp = uchar(UCHAR_MAX*temp); result.at(i,j)[k] = utemp; } result.at(i,j)[3] = input.at(i,j)[3]; } } return [CVTools UIImageFromCVMat:result]; } 6.饱和度

将RGB颜色空间转换为HLS颜色空间,HLS空间三个分量分别是色相(H)、亮度(L)、饱和度(S),通过调整S通道的数值来达到修改色相的目的,代码中有8位转32位浮点数的操作,是因为在iOS端Opencv只支持处理8位或者32位的浮点数,因项目中使用的是16位的图片,所以需要转成32位的归一化的浮点数格式来进行处理,如果是8位图片,可以考虑去除掉该转换。

//调节饱和度 +(UIImage *)saturationInPutImage:(UIImage *)inputImage value:(CGFloat)value{ cv::Mat originImgMat = [CVTools cvMatFromUIImage:inputImage]; //u8 to 32f cv::Mat folatImgMat; originImgMat.convertTo(folatImgMat,CV_32FC4,1/255.0); //32f to hls cv::Mat hlsMat = Mat(folatImgMat.size(),CV_32FC3); cvtColor(folatImgMat, hlsMat, COLOR_RGB2HLS); //处理S通道 for (int row=0; row < originImgMat.rows; row++) { for (int col=0; col < originImgMat.cols; col++) { //hlsMat.at(row,col)[1] CGFloat sValue = hlsMat.at(row,col)[2] + value; if(sValue < 0){ sValue = 0; } if(sValue > 1){ sValue = 1; } hlsMat.at(row,col)[2] = sValue; } } //hls to 32f cv::Mat hlsFloatMat = Mat(folatImgMat.size(),CV_32FC4); cvtColor(hlsMat, hlsFloatMat, COLOR_HLS2RGB); //32f to u8 cv::Mat reslutMat = Mat(folatImgMat.size(),CV_8UC4); hlsFloatMat.convertTo(reslutMat,CV_8UC4,255.0); return [CVTools UIImageFromCVMat:reslutMat]; } 7.色温

增加红绿通道,则颜色偏暖;减少红绿通道,则颜色偏冷,以达到修改色温的目的

// 调节色温 +(UIImage *)colorTemperatureInPutImage:(UIImage *)inputImage value:(CGFloat)value{ Mat input = [CVTools cvMatFromUIImage:inputImage]; // cv::Mat result = input.clone(); Mat result=Mat::zeros(input.size(),input.type()); int row = input.rows; int col = input.cols; for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { result.at(i, j)[0] = saturate_cast(input.at(i, j)[0] + value*1.3); result.at(i, j)[1] = saturate_cast(input.at(i, j)[1] + value*1.3 ); result.at(i, j)[2] = saturate_cast(input.at(i, j)[2]); //处理alpha通道 result.at(i,j)[3] = input.at(i,j)[3]; } } return [CVTools UIImageFromCVMat:result]; } 8.色相

与调整饱和度逻辑类似,将RGB颜色空间转换为HLS颜色空间,HLS空间三个分量分别是色相(H)、亮度(L)、饱和度(S),通过调整H通道的数值来达到修改色相的目的。

/// 调节色相 +(UIImage *)hueInPutImage:(UIImage *)inputImage value:(CGFloat)value{ cv::Mat originImgMat = [CVTools cvMatFromUIImage:inputImage]; //u8 to 32f cv::Mat folatImgMat; originImgMat.convertTo(folatImgMat,CV_32FC4,1/255.0); //32f to hls cv::Mat hlsMat = Mat(folatImgMat.size(),CV_32FC3); cvtColor(folatImgMat, hlsMat, COLOR_RGB2HLS); //处理H通道 for (int row=0; row < originImgMat.rows; row++) { for (int col=0; col < originImgMat.cols; col++) { //hlsMat.at(row,col)[1] CGFloat hue = hlsMat.at(row,col)[0] + value; if(hue < 0){ hue = 0; } if(hue > 360){ hue = 360; } hlsMat.at(row,col)[0] = hue; } } //hls to 32f cv::Mat hlsFloatMat = Mat(folatImgMat.size(),CV_32FC4); cvtColor(hlsMat, hlsFloatMat, COLOR_HLS2RGB); //32f to u8 cv::Mat reslutMat = Mat(folatImgMat.size(),CV_8UC4); hlsFloatMat.convertTo(reslutMat,CV_8UC4,255.0); return [CVTools UIImageFromCVMat:reslutMat]; }

代码中用到的cvMatFromUIImage方法及UIImageFromCVMat方法可移步OpenCV在iOS端的集成及Mat和UIImage互相转化(附源码) 获取



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有