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

图像均值化仅生成竖线的原因排查与代码问题分析

问题:计算图像像素均值的程序仅生成竖线

我尝试开发一个计算图像像素均值的程序,但运行后仅生成了竖线。以下是当前代码:

from typing import List

import cv2 as cv
import numpy as np


def main():
    # Importing two of the same imagae for debugigng purposes
    a = cv.imread("Datasets/OTIS/OTIS_PNG_Gray/Fixed Patterns/Pattern1/Pattern1_001.png", cv.IMREAD_GRAYSCALE)
    b = cv.imread("Datasets/OTIS/OTIS_PNG_Gray/Fixed Patterns/Pattern1/Pattern1_001.png", cv.IMREAD_GRAYSCALE)

    s = [a, b]
    avg = [[0] * len(a[0])] * len(a)
    print(f"rows: {len(a)} cols: {len(a[0])}")
    print(f"rows: {len(avg)} cols: {len(avg[0])}")

    for i in range(len(a)):
        for j in range(len(a[0])):
            # print(f"({i}, {j}): {temp_mean(s, i, j)}")
            avg[i][j] = temp_mean(s, i, j) / 255

    avim = np.array(avg)
    print(f"rows: {len(avim)} cols: {len(avim[0])}")

    cv.imshow("title", avim)

    cv.waitKey(0)


def temp_mean(seq: List[List[List[any]]], i: int, j: int):
    out = 0

    for im in seq:
        out += im[i][j]

    return out / len(seq)


if __name__ == '__main__':
    main()

原图:
原图

生成图:
生成图


问题根源

  1. 列表初始化错误:[[0] * len(a[0])] * len(a) 会创建多个指向同一行列表的引用,修改任意一行的元素时,所有行的对应位置都会被同步修改,最终导致图像呈现竖线。
  2. 类型注解不匹配:temp_mean函数的seq参数标注为List[List[List[any]]],但实际传入的是numpy数组列表,类型定义错误。
  3. 图像数据类型问题:计算后的avim为float类型,直接传入cv.imshow可能存在显示异常,需确保数据类型符合要求。

修复后的代码

from typing import List
import cv2 as cv
import numpy as np


def main():
    # 导入两张相同图片用于调试
    a = cv.imread("Datasets/OTIS/OTIS_PNG_Gray/Fixed Patterns/Pattern1/Pattern1_001.png", cv.IMREAD_GRAYSCALE)
    b = cv.imread("Datasets/OTIS/OTIS_PNG_Gray/Fixed Patterns/Pattern1/Pattern1_001.png", cv.IMREAD_GRAYSCALE)

    s = [a, b]
    # 正确初始化二维列表,避免引用重复
    avg = [[0 for _ in range(len(a[0]))] for _ in range(len(a))]
    print(f"rows: {len(a)} cols: {len(a[0])}")
    print(f"rows: {len(avg)} cols: {len(avg[0])}")

    for i in range(len(a)):
        for j in range(len(a[0])):
            avg[i][j] = temp_mean(s, i, j) / 255

    # 转换为float32类型,适配cv.imshow的显示要求
    avim = np.array(avg, dtype=np.float32)
    print(f"rows: {len(avim)} cols: {len(avim[0])}")

    cv.imshow("title", avim)
    cv.waitKey(0)
    cv.destroyAllWindows()  # 释放窗口资源


def temp_mean(seq: List[np.ndarray], i: int, j: int) -> float:
    out = 0.0
    for im in seq:
        out += im[i][j]
    return out / len(seq)


if __name__ == '__main__':
    main()

更高效的实现方式

利用numpy的广播特性可以省去手动遍历像素的步骤,大幅提升效率:

import cv2 as cv
import numpy as np

def main():
    a = cv.imread("Datasets/OTIS/OTIS_PNG_Gray/Fixed Patterns/Pattern1/Pattern1_001.png", cv.IMREAD_GRAYSCALE)
    b = cv.imread("Datasets/OTIS/OTIS_PNG_Gray/Fixed Patterns/Pattern1/Pattern1_001.png", cv.IMREAD_GRAYSCALE)
    
    # 直接计算多张图片的均值
    avg = np.mean([a, b], axis=0) / 255
    # 转换为float32类型确保显示正常
    avg = avg.astype(np.float32)
    
    cv.imshow("title", avg)
    cv.waitKey(0)
    cv.destroyAllWindows()

if __name__ == '__main__':
    main()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 17:51:45