You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OpenCV4.5.5 16位有符号图像转兼容类型实现拼贴显示报错

问题背景

我正在尝试为当前为16s格式的图像制作拼贴图。cv2.imshow()不支持该图像类型,我暂时未找到正确的图像转换方式。
补充说明: 我已知cv2.imshow()支持除16u之外的其他图像类型,因此将图像转换为任意最易实现的兼容类型均可。

原实现代码如下:

import cv2
import numpy as np
import glob
import os
import shutil
from PIL import Image

source_path = "C:/Users/source/path/"
destination_path = "C:/Users/destination/path"

#copy raw files only from source, and rename them in im1.png, im2.png etc format

if os.path.exists(destination_path):
    print("destination file already exists")
else:
        dir = os.mkdir(destination_path)
        files = glob.iglob(os.path.join(source_path, "*raw.png"))
        for file in files:
            if os.path.isfile(file):
                shutil.copy2(file, destination_path)

#resize images and flip
for file_name in os.listdir(destination_path):
    image = Image.open(os.path.join(destination_path, file_name))
    new_dimensions = (50, 50)
    output = image.resize(new_dimensions, Image.ANTIALIAS).transpose(Image.FLIP_TOP_BOTTOM)
    output_file_name = os.path.join(destination_path, file_name)
    output.save(output_file_name, quality = 95)


count=1

#rename the files
for file_name in os.listdir(destination_path):
    
    source = destination_path + file_name
    destination = destination_path + "im" + str(count) + ".png"
    os.rename(source, destination)
    globals()["im" + str(count)] = destination
    
    count += 1

#create collage
h_stack1 = np.hstack([im7,im6,im5,im4,im3,im2,im1])
h_stack2 = np.hstack([im8,im9,im10,im11,im12,im13,im14])
h_stack3 = np.hstack([im21,im20,im19,im18,im17,im16,im15])
h_stack4 = np.hstack([im22,im23,im24,im25,im26,im27,im28])
h_stack5 = np.hstack([im35,im34,im33,im32,im31,im30,im29])
h_stack6 = np.hstack([im36,im37,im38,im39,im40,im41,im42])
h_stack7 = np.hstack([im49,im48,im47,im46,im45,im44,im43])
    
v_stack = np.vstack([h_stack1,h_stack2,h_stack3,h_stack4,h_stack5,h_stack6,h_stack7])
    
cv2.imshow("collage",v_stack)
cv2.imsave("collage.png",v_stack)
cv2.waitKey(0)
cv2.destroyAllWindows()

运行最后4行代码时触发如下报错:

Overload resolution failed:

  • mat data type = 19 is not supported
  • Expected Ptrcv::cuda::GpuMat for argument 'mat'
  • Expected Ptrcv::UMat for argument 'mat'
问题原因
  • 核心错误:通过globals()动态生成的im1/im2...变量存的是图片文件的路径字符串,不是OpenCV可识别的图像矩阵对象,直接拿字符串做numpy拼接得到的是字符串数组,传给cv2接口自然会报数据类型不支持的错误(numpy字符串类型的dtype编号恰好为19,和报错信息完全对应)。
  • 兼容问题:就算正确读取了图像,16s(16位有符号整数)格式直接传入cv2.imshow/cv2.imwrite也存在兼容问题,转成通用的8位无符号整数(CV_8U,取值范围0-255)格式兼容性最好。
  • 其他bug:路径拼接时没有加分隔符,会生成错误路径;保存图像的函数名写错,OpenCV没有cv2.imsave接口,正确接口是cv2.imwrite。
修正方案
  • 重命名文件时不再存路径字符串,所有文件重命名完成后,统一按文件名顺序读取图像,同步完成16s到8位格式的转换,把合法的图像矩阵存入列表备用。
  • 所有路径拼接统一使用os.path.join,避免分隔符缺失导致的路径错误。
  • 修正保存图像的接口名。
  • 按预设的排列顺序从图像列表中取对应矩阵做横向、纵向拼接。

修正后的完整代码:

import cv2
import numpy as np
import glob
import os
import shutil
from PIL import Image

source_path = "C:/Users/source/path/"
destination_path = "C:/Users/destination/path/"

# 复制源目录下raw.png文件
if os.path.exists(destination_path):
    print("destination file already exists")
else:
    os.mkdir(destination_path)
    files = glob.iglob(os.path.join(source_path, "*raw.png"))
    for file in files:
        if os.path.isfile(file):
            shutil.copy2(file, destination_path)

# 调整图像尺寸、翻转
for file_name in os.listdir(destination_path):
    image = Image.open(os.path.join(destination_path, file_name))
    new_dimensions = (50, 50)
    output = image.resize(new_dimensions, Image.ANTIALIAS).transpose(Image.FLIP_TOP_BOTTOM)
    output_file_name = os.path.join(destination_path, file_name)
    output.save(output_file_name, quality = 95)

count = 1
# 重命名文件
for file_name in os.listdir(destination_path):
    source = os.path.join(destination_path, file_name)
    destination = os.path.join(destination_path, f"im{count}.png")
    os.rename(source, destination)
    count += 1

# 读取所有图像,转成cv2兼容的8位格式
img_list = []
for i in range(1, count):
    img_path = os.path.join(destination_path, f"im{i}.png")
    # 保留原始位深读取
    img = cv2.imread(img_path, cv2.IMREAD_UNCHANGED)
    # 16s格式转8位无符号格式
    if img.dtype == np.int16:
        img = img.astype(np.float32)
        # 像素值归一化到0-255区间
        img = (img - img.min()) / (img.max() - img.min()) * 255
        img = img.astype(np.uint8)
    img_list.append(img)

# 按预设顺序拼接,列表索引从0开始,im1对应索引0,im7对应索引6
h_stack1 = np.hstack([img_list[6], img_list[5], img_list[4], img_list[3], img_list[2], img_list[1], img_list[0]])
h_stack2 = np.hstack([img_list[7], img_list[8], img_list[9], img_list[10], img_list[11], img_list[12], img_list[13]])
h_stack3 = np.hstack([img_list[20], img_list[19], img_list[18], img_list[17], img_list[16], img_list[15], img_list[14]])
h_stack4 = np.hstack([img_list[21], img_list[22], img_list[23], img_list[24], img_list[25], img_list[26], img_list[27]])
h_stack5 = np.hstack([img_list[34], img_list[33], img_list[32], img_list[31], img_list[30], img_list[29], img_list[28]])
h_stack6 = np.hstack([img_list[35], img_list[36], img_list[37], img_list[38], img_list[39], img_list[40], img_list[41]])
h_stack7 = np.hstack([img_list[48], img_list[47], img_list[46], img_list[45], img_list[44], img_list[43], img_list[42]])

v_stack = np.vstack([h_stack1,h_stack2,h_stack3,h_stack4,h_stack5,h_stack6,h_stack7])

cv2.imshow("collage",v_stack)
cv2.imwrite("collage.png",v_stack)
cv2.waitKey(0)
cv2.destroyAllWindows()

内容的提问来源于stack exchange,提问作者user19042201

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.31 20:33:17