Я хочу реализовать smth-подобную кривую тона.OpenCV Tone Curve progrommatically
У меня есть предопределенный набор кривых, которые я должен применить к изображению. Например:
, как я понимаю, на этом графике мы видим зависимости текущего значения тона на новые, например: , если мы получим первую точку слева - каждый г, г и Ь, что = 0 будет преобразуется в 64 или каждое значение более 224 будет преобразовано в 0 и ect.
поэтому я попытался изменить каждый пиксель изображения на новое значение
для целей тестирования я упростил кривой:
и здесь код у меня есть:
//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 изображения был обработан
и не совпадения с результатом я ожидаемому:
Update 0
благодаря @ACCurrent комментарий обнаружены ошибки в вычислении (обновлены код и изображение), но до сих пор не понятно, почему обрабатывается только 3/4 изображений.
не уверен, что поймите, почему появляется «шум», надеюсь, что из-за кривой негладкой.
выглядит так, чтобы избежать .at
операции.
Update 1
исходное изображение:
Избегайте использования opencv '.при функции <> 'это очень медленно. Также при первой проверке допустим значение на 'gaussMat.at (y, x) [c]' = 128 Затем: 'if ((gaussMat.at (y, x) [c]> 64) && (gaussMat.at (y, x) [c] <= 128)) outMat.at (y, x) [c] = (gaussMat.at (y, x) [c]) - 64 + (gaussMat.at (y, x) [c]) * 4' Таким образом, 128-64 + 128 * 4 равно 576, что превышает 255 максимальное значение для CV_U8c. Поэтому будет насыщенность. –
ACCurrent
Вы также можете опубликовать исходное изображение? И не волнуйтесь ... функция 'at' не медленная. Вы можете использовать его без каких-либо проблем. – Miki
@Miki исходное изображение добавлено – user5599807