在OpenCV Python中从图像中减去晕映模板

aij0ehis  于 2022-12-19  发布在  Python
关注(0)|答案(1)|浏览(152)

我有750多张像'test.png'这样的图片,我需要减去'vig-raw.png'中的暗角,我刚刚开始使用opencv-python,所以“我甚至不知道我不知道什么”。
使用GIMP,我对'vig-raw.png'进行去饱和处理以创建'vig-desat.png',然后使用Color将其转换为Alpha以创建'vig-alpha.png'
这是我尝试从'test.png'中减去'vig-alpha.png'

import cv2 as cv
import numpy as np

img1 = cv.imread('test.png',0)
img1 = cv.cvtColor(img1, cv.COLOR_BGR2BGRA) # add alpha channel to RGB image
print(img1[0][0]) # show alpha

img2 = cv.imread('vig-alpha.png',flags=cv.IMREAD_UNCHANGED) # read RGBA image
print(img2[0][0]) #show alpha

img3 = cv.subtract(img1, img2)
img3 = cv.resize(img3, (500,250))
print(img3[0][0]) # show alpha

cv.imshow('result',img3)
cv.waitKey()
cv.destroyAllWindows()

然而,这是'result'。我需要在整个图像中产生均匀的阴影,同时保持原始颜色不变。我不知道这类事情的正确术语,而且很难用我所知道的来寻找解决方案。提前感谢。
编辑:根据Rotem的回答,图像文件格式很重要。StackOverflow将我发布的PNG文件转换为JPEG,这在检查他们的回答时确实影响了结果。查看我在下面Rotem的回答上留下的评论以了解更多信息。

cyvaqqii

cyvaqqii1#

晕影模板不应被减去,而应被缩放
渐晕校正过程称为Flat-field correction,适用于:
第一个月
C = (R - D) * G
D为暗场或暗帧时。
我们没有暗帧样本-我们可以假设暗帧全为零。
假设D = 0,则校正公式为:
G = m / F
C = R * G
m = mean(F),并且F适用于vig-alpha
是一米九氮一。
对于计算G(将其命名为inv_vig_norm,我们可以使用以下阶段):

  • 读取vig-alpha.png作为灰度,并将其转换为范围[0,1]内的浮点型(vig_norm应用F):
vig = cv2.imread('vig-alpha.png', cv2.IMREAD_GRAYSCALE)
 vig_norm = vig.astype(np.float32) / 255
  • m除以F
vig_mean_val = cv2.mean(vig_norm)[0]
 inv_vig_norm = vig_mean_val / vig_norm  # Compute G = m/F
  • 计算C = R * G-用inv_vig_norm缩放img1
inv_vig_norm = cv2.cvtColor(inv_vig_norm, cv2.COLOR_GRAY2BGR)
 img2 = cv2.multiply(img1, inv_vig_norm, dtype=cv2.CV_8U)  # Compute: C = R * G

为了去除噪声和伪影,我们可能会在vig上应用中值模糊和高斯模糊(可能需要,因为网站将vig-alpha.png转换为JPEG格式)。
代码示例:

import cv2
import numpy as np

img1 = cv2.imread('test.png')

vig = cv2.imread('vig-alpha.png', cv2.IMREAD_GRAYSCALE)  # Read vignette template as grayscale

vig = cv2.medianBlur(vig, 15)  # Apply median filter for removing artifacts and extreem pixels.

vig_norm = vig.astype(np.float32) / 255  # Convert vig to float32 in range [0, 1]
vig_norm = cv2.GaussianBlur(vig_norm, (51, 51), 30)  # Blur the vignette template (because there are still artifacts, maybe because SO convered the image to JPEG).
#vig_max_val = vig_norm.max()  # For avoiding "false colors" we may use the maximum instead of the mean.
vig_mean_val = cv2.mean(vig_norm)[0]
# vig_max_val / vig_norm
inv_vig_norm = vig_mean_val / vig_norm  # Compute G = m/F

inv_vig_norm = cv2.cvtColor(inv_vig_norm, cv2.COLOR_GRAY2BGR)  # Convert inv_vig_norm to 3 channels before using cv2.multiply. https://stackoverflow.com/a/48338932/4926757

img2 = cv2.multiply(img1, inv_vig_norm, dtype=cv2.CV_8U)  # Compute: C = R * G

cv2.imshow('inv_vig_norm',  cv2.resize(inv_vig_norm / inv_vig_norm.max(), (500, 250)))  # Show inv_vig_norm for testing
cv2.imshow('img1', cv2.resize(img1, (500, 250)))
cv2.imshow('result', cv2.resize(img2, (500, 250)))
cv2.waitKey()
cv2.destroyAllWindows()

结果:
img1

inv_vig_norm

img2

相关问题