代码如下:
from PIL import Image
import numpy as np
path_rgb = Image.open('.png')#打开图片
path_normal = Image.open('.png')
# print("path_rgb:",path_img)
#输出:path_rgb: <PIL.PngImagePlugin.PngImageFile image mode=RGB size=1280x720 at
img_rgb = np.asarray(path_rgb)#将输入的图片转为矩阵格式
# print(img_rgb)
#输出:图片的矩阵格式
# print("H W C:",img_rgb.shape)
#输出:H W C: (720, 1280, 3)
img_normal = np.asarray(path_normal)
total = img_rgb*0.5 + img_normal*0.5#矩阵相加
img = Image.fromarray(np.uint8(total*255))#矩阵转图片
img.show()#展示图片
原因:Image.open采用读入图片数组,注意这里读入的数组是 PIL.PngImagePlugin.PngImageFile型,是 uinit8 型的,范围是0-255。
其中,
Image.fromarray 归一化处理,就是实现array到image的转换
多写了一个深度图与RGB图融合的代码:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import rospy
import cv2
from cv_bridge import CvBridge
from sensor_msgs.msg import Image
import numpy as np
from PIL import Image as Img
rgb_ratio = 0.5
normal_ratio = 0.5
class image_converter:
def __init__(self):
# 创建cv_bridge,声明图像的发布者和订阅者
# self.image_pub = rospy.Publisher("cv_bridge_image", Image, queue_size=1)
self.bridge = CvBridge()
self.rgb_sub = rospy.Subscriber("/camera/color/image_raw", Image, self.rgb_callback)
self.depth_sub = rospy.Subscriber("/camera/depth/image_rect_raw", Image, self.depth_callback)
def rgb_callback(self,data):
# 使用cv_bridge将ROS的图像数据转换成OpenCV的图像格式
rgb_image = self.bridge.imgmsg_to_cv2(data, "rgb8")
# rgb_image = Img.fromarray(cv2.cvtColor(rgb_img, cv2.COLOR_BGR2RGB))
# rgb_image = cv2.resize(rgb_img,(848,600))
# rgb_image = rgb_image[120:600]
# 显示Opencv格式的图像
# cv2.imshow("Image window1", rgb_image)
# cv2.waitKey(3)
global rgb_array
rgb_array = np.asarray(rgb_image)
# 再将opencv格式额数据转换成ros image格式的数据发布
# try:
# self.image_pub.publish(self.bridge.cv2_to_imgmsg(cv_image, "bgr8"))
# except CvBridgeError as e:
# print (e)
def depth_callback(self,data):
# 使用cv_bridge将ROS的图像数据转换成OpenCV的图像格式
depth_image = self.bridge.imgmsg_to_cv2(data, "16UC1")
M = np.float32([[1, 0, -36], [0, 1, 0]]) #深度图向左移动对齐
depth_image = cv2.warpAffine(depth_image, M, (depth_image.shape[1], depth_image.shape[0]))
# cv2.imshow("Image window2", depth_image)
# cv2.waitKey(3)
rows, cols = depth_image.shape
x, y = np.meshgrid(np.arange(cols), np.arange(rows))
x = x.astype(np.float32)
y = y.astype(np.float32)
# Calculate the partial derivatives of depth with respect to x and y
dx = cv2.Sobel(depth_image, cv2.CV_32F, 1, 0)
dy = cv2.Sobel(depth_image, cv2.CV_32F, 0, 1)
# Compute the normal vector for each pixel
normal = np.dstack((-dx, -dy, np.ones((rows, cols))))
norm = np.sqrt(np.sum(normal**2, axis=2, keepdims=True))
normal = np.divide(normal, norm, out=np.zeros_like(normal), where=norm != 0)
# Map the normal vectors to the [0, 255] range and convert to uint8
normal = (normal + 1) * 127.5
normal = normal.clip(0, 255).astype(np.uint8)
# Save the normal map to a file
normal_image = cv2.cvtColor(np.uint8(normal), cv2.COLOR_RGB2BGR)
# normal_image = Img.fromarray(cv2.cvtColor(normal_img, cv2.COLOR_BGR2RGB))
global normal_array
normal_array = np.asarray(normal_image)
# print(normal_array)
# 再将opencv格式额数据转换成ros image格式的数据发布
# try:
# self.image_pub.publish(self.bridge.cv2_to_imgmsg(cv_image, "bgr8"))
# except CvBridgeError as e:
# print (e)
# def __del__(self):
total_array = rgb_array * rgb_ratio + normal_array * normal_ratio
total_img = Img.fromarray(np.uint8(total_array)).convert('RGB')
# total_img.show()
show_img = cv2.cvtColor(np.uint8(total_img), cv2.COLOR_RGB2BGR)
cv2.imshow("Image window", show_img)
cv2.waitKey(3)
# print (total_array)
if __name__ == '__main__':
try:
# 初始化ros节点
rospy.init_node("cv_bridge_test")
rospy.loginfo("Starting cv_bridge_test node")
image_converter()
rospy.spin()
except KeyboardInterrupt:
print ("Shutting down cv_bridge_test node.")
cv2.destroyAllWindows()