我正在编写一个脚本来修改RGB图像的亮度,使用NumPy和CV2通过从RGB转换为YCrCb再返回。但是,我正在使用的循环需要一段时间才能执行,我想知道是否有更快的方法。
import cv2 as cv, numpy as np
threshold = 64
image = cv.imread("motorist.jpg", -1)
image.shape # Evaluates to (1000, 1500, 3)
im = cv.cvtColor(image, cv.COLOR_RGB2YCR_CB)
for row in image:
for col in row:
if col[0] > threshold:
col[0] = threshold
image = cv.cvtColor(im, cv.COLOR_YCR_CB2RGB)
cv.imwrite("motorist_filtered.jpg", image)
实现阈值比较的嵌套循环至少需要5-7秒才能执行。是否有更快的方法来实现此功能?
答案 0 :(得分:15)
我们的想法是创建一个mask,让你可以使用numpy的矢量化。由于形状为(n,m,3)
,因此在前两个维度上循环并使用[:,:,0]
idx = image[:,:,0] > threshold
image[idx,0] = threshold
答案 1 :(得分:3)
您可以使用clip
:
用法:
result = im.copy()
result[..., 0] = np.clip(im[..., 0], 0, threshold)
或者就地修改:
np.clip(im[..., 0], 0, threshold, out=im[..., 0])
答案 2 :(得分:1)
import numpy as np
image[..., 0] = np.minimum(image[..., 0], threshold)
编辑:对不起,我还无法添加评论。我昨天感觉很懒。关于就地修改是真的,但它是相当明显的,或者你不需要它。懒惰是对一个懒惰问题的回应 - 在numpy中有一个'一切'的功能 - 只需检查文档。
答案 3 :(得分:0)
我使用以下代码:
def threshold_image(self, image, threshold=5, value=0, smaller=True):
image = image.copy()
idx = image[:, :, :] < threshold if smaller else image[:,:,:] > threshold
image[idx] = value
return image