OpenCV Tone Curve progrommatically

2020-06-25 05:01发布

I want to realize smth like tone curve.

I have predefined set of curves that I should apply to the image. For instance: enter image description here

as I understand on this chart we see dependences of current tone value to new, for example: if we get first dot on the left - every r,g and b that = 0 will be converted to 64 or every value more than 224 will be converted to 0 and ect.

so I tried to change every pixel of image to new value

for test purpose i've simplified curve:

enter image description here

and here the code I have:

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

but here the result I get: enter image description here

by some reason only 3/4 of image was processed

and it not matches with result i expected: enter image description here

Update 0

thanks to @ACCurrent comment found errors in calculation(code and image updated), but still not understand why only 3/4 of images processed.

not sure that understand why 'noise' appears, hope it because of curve not smooth.

looks the way to avoid .at operation.

Update 1

original image:

enter image description here

1条回答
可以哭但决不认输i
2楼-- · 2020-06-25 05:08

You need to access the images with Vec4b


originalMat.type() is equals to 24

Your originalMat is of type 24, i.e. CV_8UC4. This means that the image has 4 channels, but you're accessing it with Vec3b as if it has only 3 channels. This explains why about 1/4 of the image is not modified.

So, simply replace every Vec3b in your code with Vec4b.

查看更多
登录 后发表回答