-
需求:
将经过mask-rcnn分割得到的结果图与原图进行融合,生成mask覆盖在原图上的图。
-
将黑白二值图转化为紫色/黑色二值图的几种方法:
1. 遍历图片像素并修改像素RBG值
import cv2
import numpy as np
import time
start = time.time()
# 读入图片
original = cv2.imread('/code-server/funkydog/cv/original.jpg')
mask = cv2.imread('/code-server/funkydog/cv/mask1.png')
height,width,channels = mask.shape
# 将numpy转成list
mask_list = mask.tolist()
for i in range(height):
for j in range(width):
if mask_list[i][j] == [255,255,255]:
mask_list[i][j] = [139,5,139]
mask = np.array(mask_list,dtype=mask.dtype)
print(time.time()-start)
# 融合
res = cv2.addWeighted(original,1,mask,0.5,0)
cv2.imwrite('out.jpg', res)
print(time.time()-start)
这种方法下的耗时严重,因为将图片数据转为python内置list再由python遍历最后又转为numpy数组经历了多次数据转化,会严重拖慢速度,且python的速度一直被诟病,如果能使用到numpy的c模块进行加速应该会好很多。
2.尝试在numpy中进行遍历:
import cv2
import numpy as np
import time
start = time.time()
# 读入图片
original = cv2.imread('/code-server/funkydog/cv/original.jpg')
mask = cv2.imread('/code-server/funkydog/cv/mask1.png')
height,width,channels = mask.shape
# 定义一个黑色像素用于对比
black = np.array([0,0,0])
# 需要转化的颜色像素
color = np.array([139,0,139])
# 遍历numpy数组
for row in range(height):
for col in range(width):
# 将像素点与黑色像素做对比
if (black!=mask[row][col]).all():
# 将白色像素换成黑色
mask[row][col] = color
print(time.time()-start)
# 融合
res = cv2.addWeighted(original,1,mask,0.5,0)
cv2.imwrite('out.jpg', res)
print(time.time()-start)
然而这次的耗时更为严重,直接翻倍了...也许在调用numpy数据对比的.all() API耗费了大量时间
3.终极解决方案完全使用opencv的内置c++动态库函数
import cv2
import numpy as np
import time
start = time.time()
original = cv2.imread('/code-server/funkydog/cv/original.jpg')
mask = cv2.imread('/code-server/funkydog/cv/mask1.png')
# 分割rgb通道
b_channel, g_channel, r_channel = cv2.split(mask)
# 使用cv2.threshold函数,输入BRG三个通道的灰度图像,和触发阈值,和转换值,还有触发器类型
ret1,b = cv2.threshold(b_channel,1,139,cv2.THRESH_BINARY)
ret2,g = cv2.threshold(g_channel,1,5,cv2.THRESH_BINARY)
ret3,r = cv2.threshold(r_channel,1,139,cv2.THRESH_BINARY)
dst = cv2.merge((b,g,r))
print(time.time()-start)
res = cv2.addWeighted(original,1,dst,0.5,0)
cv2.imwrite('out.jpg', res)
print(time.time()-start)