python - 如何有效地将函数应用于图像中每个像素的每个通道(用于颜色转换)?
问题描述
我正在尝试实施 Reinhard 的方法,以使用目标图像的颜色分布对研究项目传入的图像进行颜色归一化。我已经让代码正常工作并且输出正确,但速度很慢。遍历 300 张图像大约需要 20 分钟。我很确定瓶颈是我如何处理将函数应用于每个图像。我目前正在遍历图像的每个像素并将下面的函数应用于每个通道。
def reinhard(target, img):
#converts image and target from BGR colorspace to l alpha beta
lAB_img = cv2.cvtColor(img, cv2.COLOR_BGR2Lab)
lAB_tar = cv2.cvtColor(target, cv2.COLOR_BGR2Lab)
#finds mean and standard deviation for each color channel across the entire image
(mean, std) = cv2.meanStdDev(lAB_img)
(mean_tar, std_tar) = cv2.meanStdDev(lAB_tar)
#iterates over image implementing formula to map color normalized pixels to target image
for y in range(512):
for x in range(512):
lAB_tar[x, y, 0] = (lAB_img[x, y, 0] - mean[0]) / std[0] * std_tar[0] + mean_tar[0]
lAB_tar[x, y, 1] = (lAB_img[x, y, 1] - mean[1]) / std[1] * std_tar[1] + mean_tar[1]
lAB_tar[x, y, 2] = (lAB_img[x, y, 2] - mean[2]) / std[2] * std_tar[2] + mean_tar[2]
mapped = cv2.cvtColor(lAB_tar, cv2.COLOR_Lab2BGR)
return mapped
我的主管告诉我,我可以尝试使用矩阵一次性应用该函数以改善运行时间,但我不确定如何去做。
解决方案
原文和目标:</p>
使用 Reinhard 方法的颜色转移结果5 ms
:
我更喜欢numpy vectorized operations
在python loops
.
# implementing the formula
#(Io - mo)/so*st + mt = Io * (st/so) + mt - mo*(st/so)
ratio = (std_tar/std_ori).reshape(-1)
offset = (mean_tar - mean_ori*std_tar/std_ori).reshape(-1)
lab_tar = cv2.convertScaleAbs(lab_ori*ratio + offset)
这是代码:
# 2019/02/19 by knight-金
# https://stackoverflow.com/a/54757659/3547485
import numpy as np
import cv2
def reinhard(target, original):
# cvtColor: COLOR_BGR2Lab
lab_tar = cv2.cvtColor(target, cv2.COLOR_BGR2Lab)
lab_ori = cv2.cvtColor(original, cv2.COLOR_BGR2Lab)
# meanStdDev: calculate mean and stadard deviation
mean_tar, std_tar = cv2.meanStdDev(lab_tar)
mean_ori, std_ori = cv2.meanStdDev(lab_ori)
# implementing the formula
#(Io - mo)/so*st + mt = Io * (st/so) + mt - mo*(st/so)
ratio = (std_tar/std_ori).reshape(-1)
offset = (mean_tar - mean_ori*std_tar/std_ori).reshape(-1)
lab_tar = cv2.convertScaleAbs(lab_ori*ratio + offset)
# convert back
mapped = cv2.cvtColor(lab_tar, cv2.COLOR_Lab2BGR)
return mapped
if __name__ == "__main__":
ori = cv2.imread("ori.png")
tar = cv2.imread("tar.png")
mapped = reinhard(tar, ori)
cv2.imwrite("mapped.png", mapped)
mapped_inv = reinhard(ori, tar)
cv2.imwrite("mapped_inv.png", mapped)
推荐阅读
- javascript - 使用延迟加载时如何在 Angular 中动态构建导航?
- dart - 使用 dart 的 Telnet 协议
- r - r:在 ggplot 图中插入 ggtexttable()
- html - Cordova,HTML5 视频不响应触摸输入
- python - 收到错误“modulenotfounderror:没有名为“google”的模块”,但是当尝试通过命令提示符安装时,它说要求已经满足
- java - 如何为 ActiveMQ 队列创建 Spring Boot 消费者?
- javascript - 循环遍历 Javascript 对象以构建嵌套列表
- java - 将文本作为短信中的超链接
- reactjs - 可以从反应应用程序中打开“位智”吗?
- linux - Kubernetes 中的 UDP 发送和接收