OpenCV 色调曲线编程

OpenCV Tone Curve progrommatically

我想实现色调曲线之类的东西

我已经预定义了一组应用于图像的曲线。 例如:

据我了解,在这张图表上我们看到了当前音调值对新音调值的依赖性,例如: 如果我们得到左边的第一个点 - 每个 = 0 的 r、g 和 b 都将转换为 64 或每个大于 224 的值将被转换为 0 等。

所以我尝试将图像的每个像素更改为新值

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

这里是我的代码:

//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];

但我得到的结果是:

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

它与我预期的结果不匹配:

更新0

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

不太明白为什么会出现'noise',希望是因为曲线不平滑。

寻找避免.at操作的方法。

更新 1

原图:

您需要使用 Vec4b

访问图像

originalMat.type() is equals to 24

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

因此,只需将代码中的每个 Vec3b 替换为 Vec4b