OpenCV Tone Curve以程序方式进行

时间:2017-02-08 00:11:45

标签: ios opencv opencv3.0 objective-c++ opencv3.1

我希望像音色曲线一样实现smth。

我有一组预定义的曲线应该应用于图像。 例如: enter image description here

正如我在此图表中所理解的那样,我们看到当前音调值与新音色的依赖关系,例如: 如果我们在左边得到第一个点 - 每个r,g和b = 0将转换为64 或者超过224的每个值都将转换为0等等。

因此我尝试将图像的每个像素更改为新值

出于测试目的,我简化了曲线:

enter image description here

这里是我的代码:

//init original image
cv::Mat originalMat = [self cvMatFromUIImage:inputImage];

//out image the same size
cv::Mat outMat      = [self cvMatFromUIImage:inputImage];

//loop throw every row of image
for( int y = 0; y < originalMat.rows; y++ ){
    //loop throw every column of image
   for( int x = 0; x < originalMat.cols; x++ ){
     //loop throw every color channel of image (R,G,B)
     for( int c = 0; c < 3; c++ ){

        if(originalMat.at<cv::Vec3b>(y,x)[c] <= 64)
       outMat.at<cv::Vec3b>(y,x)[c] = 64 + ( originalMat.at<cv::Vec3b>(y,x)[c] ) -
        ( originalMat.at<cv::Vec3b>(y,x)[c] ) * 2    ;

        if((originalMat.at<cv::Vec3b>(y,x)[c] > 64)&&(originalMat.at<cv::Vec3b>(y,x)[c] <= 128))
        outMat.at<cv::Vec3b>(y,x)[c] = (( originalMat.at<cv::Vec3b>(y,x)[c] ) - 64  ) * 4
        ;

        if((originalMat.at<cv::Vec3b>(y,x)[c] > 128))
        outMat.at<cv::Vec3b>(y,x)[c] = ( originalMat.at<cv::Vec3b>(y,x)[c] ) + 128 -
        (( originalMat.at<cv::Vec3b>(y,x)[c] ) - 128)  * 3;

     } //end of r,g,b loop
   } //end of column loop
 } //end of row loop

//send to output
return [self UIImageFromCVMat:outMat];

但是我得到的结果是: enter image description here

由于某种原因只处理了3/4的图像

并且它与我预期的结果不匹配: enter image description here

更新0

感谢 @ACCurrent 评论发现计算错误(代码和图片更新),但仍然不明白为什么只处理了3/4的图像。

不确定是否理解为什么&#39;噪音&#39;出现,希望它因为曲线不顺畅。

看起来避免.at操作的方法。

更新1

原始图片:

enter image description here

1 个答案:

答案 0 :(得分:3)

您需要使用Vec4b

访问图像
  

originalMat.type()等于24

您的originalMat属于类型24,即CV_8UC4。这意味着该图片有4个频道,但您使用Vec3b访问它,就像它只有3个频道一样。这解释了为什么大约1/4的图像没有被修改。

因此,只需使用Vec3b替换代码中的每个Vec4b