如何在 OpenCV 中的两个图像之间应用 SoftLight 混合器?
How to apply SoftLight blender between two images in OpenCV?
关于 this post on Whosebug (and this too) 我正在拍摄一张正常的花朵图像,然后是一张白色图像,然后应用柔光。
这些是图像(花和白色图像):
结果应该与我在 GIMP 中得到的结果类似:
但它最终是 白色图像。
我修改了代码以便将其放入函数中,这是我的代码:
// function
uint convSoftLight(int A, int B) {
return ((uint)((B < 128)?(2*((A>>1)+64))*((float)B/255):(255-(2*(255-((A>>1)+64))*(float)(255-B)/255))));
}
void function() {
Mat flower = imread("/Users/rafaelruizmunoz/Desktop/flower.jpg");
Mat white_flower = Mat::zeros(Size(flower.cols, flower.rows), flower.type());
Mat mix = Mat::zeros(Size(flower.cols, flower.rows), flower.type());
for (int i = 0; i < white_flower.rows; i++) {
for (int j = 0; j < white_flower.cols; j++) {
white_flower.at<Vec3b>(i,j) = Vec3b(255,255,255);
}
}
imshow("flower", flower);
imshow("mask_white", white_flower);
for (int i = 0; i < mix.rows; i++) {
for (int j = 0; j < mix.cols; j++) {
Vec3b vec = flower.at<Vec3b>(i,j);
vec[0] = convSoftLight(vec[0], 255); // 255 or just the white_flower pixel at (i,j)
vec[1] = convSoftLight(vec[1], 255); // 255 or just the white_flower pixel at (i,j)
vec[2] = convSoftLight(vec[2], 255); // 255 or just the white_flower pixel at (i,j)
mix.at<Vec3b>(i,j) = vec;
}
}
imshow("mix", mix);
}
我做错了什么?
谢谢。
编辑:我尝试翻转顺序(convSoftLight(B,A);
而不是 convSoftLight(A,B)
),但什么也没发生(黑色图像)
基于blender definitions:我重写了我的函数:
uint convSoftLight(int A, int B) {
float a = (float)A / 255;
float b = (float)B / 255;
float result = 0;
if (b < 0.5)
result = 2 * a * b + pow(a,2) * (1 - 2*b);
else
result = 2 * a * (1-b) + sqrt(a) * (2*b - 1);
return (uint)255* result;
}
以下是如何在 Python(使用 OpenCV 和 NumPy)中实现柔光:
import numpy as np
def applySoftLight(bottom, top, mask):
""" Apply soft light blending
"""
assert all(image.dtype == np.float32 for image in [bottom, top, mask])
blend = np.zeros(bottom.shape, dtype=np.float32)
low = np.where((top < 0.5) & (mask > 0))
blend[low] = 2 * bottom[low] * top[low] + bottom[low] * bottom[low] * (1 - 2 * top[low])
high = np.where((top >= 0.5) & (mask > 0))
blend[high] = 2 * bottom[high] * (1 - top[high]) + np.sqrt(bottom[high]) * (2 * top[high] - 1)
# alpha blending accroding to mask
result = bottom * (1 - mask) + blend * mask
return result
所有矩阵必须是单通道二维矩阵转换成np.float32
类型。掩码是"layer mask" GIMP/Photoshop.
关于 this post on Whosebug (and this too) 我正在拍摄一张正常的花朵图像,然后是一张白色图像,然后应用柔光。
这些是图像(花和白色图像):
结果应该与我在 GIMP 中得到的结果类似:
但它最终是 白色图像。
我修改了代码以便将其放入函数中,这是我的代码:
// function
uint convSoftLight(int A, int B) {
return ((uint)((B < 128)?(2*((A>>1)+64))*((float)B/255):(255-(2*(255-((A>>1)+64))*(float)(255-B)/255))));
}
void function() {
Mat flower = imread("/Users/rafaelruizmunoz/Desktop/flower.jpg");
Mat white_flower = Mat::zeros(Size(flower.cols, flower.rows), flower.type());
Mat mix = Mat::zeros(Size(flower.cols, flower.rows), flower.type());
for (int i = 0; i < white_flower.rows; i++) {
for (int j = 0; j < white_flower.cols; j++) {
white_flower.at<Vec3b>(i,j) = Vec3b(255,255,255);
}
}
imshow("flower", flower);
imshow("mask_white", white_flower);
for (int i = 0; i < mix.rows; i++) {
for (int j = 0; j < mix.cols; j++) {
Vec3b vec = flower.at<Vec3b>(i,j);
vec[0] = convSoftLight(vec[0], 255); // 255 or just the white_flower pixel at (i,j)
vec[1] = convSoftLight(vec[1], 255); // 255 or just the white_flower pixel at (i,j)
vec[2] = convSoftLight(vec[2], 255); // 255 or just the white_flower pixel at (i,j)
mix.at<Vec3b>(i,j) = vec;
}
}
imshow("mix", mix);
}
我做错了什么?
谢谢。
编辑:我尝试翻转顺序(convSoftLight(B,A);
而不是 convSoftLight(A,B)
),但什么也没发生(黑色图像)
基于blender definitions:我重写了我的函数:
uint convSoftLight(int A, int B) {
float a = (float)A / 255;
float b = (float)B / 255;
float result = 0;
if (b < 0.5)
result = 2 * a * b + pow(a,2) * (1 - 2*b);
else
result = 2 * a * (1-b) + sqrt(a) * (2*b - 1);
return (uint)255* result;
}
以下是如何在 Python(使用 OpenCV 和 NumPy)中实现柔光:
import numpy as np
def applySoftLight(bottom, top, mask):
""" Apply soft light blending
"""
assert all(image.dtype == np.float32 for image in [bottom, top, mask])
blend = np.zeros(bottom.shape, dtype=np.float32)
low = np.where((top < 0.5) & (mask > 0))
blend[low] = 2 * bottom[low] * top[low] + bottom[low] * bottom[low] * (1 - 2 * top[low])
high = np.where((top >= 0.5) & (mask > 0))
blend[high] = 2 * bottom[high] * (1 - top[high]) + np.sqrt(bottom[high]) * (2 * top[high] - 1)
# alpha blending accroding to mask
result = bottom * (1 - mask) + blend * mask
return result
所有矩阵必须是单通道二维矩阵转换成np.float32
类型。掩码是"layer mask" GIMP/Photoshop.