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

多图像亮度均值与标准差计算代码问题求助

图像亮度与标准差计算问题排查及修复

问题根源分析

你的代码在计算标准差时,错误地将mask外的0值像素纳入了计算范围。即使mask内是纯黑/纯白像素,mask外的大量0会拉低整体均值,导致标准差不为0。另外,多张图像的标准差计算逻辑也存在统计错误。

具体修复点

  1. 单张图像仅计算mask内有效像素:从图像中提取mask覆盖区域的像素再计算标准差,避免无效像素干扰。
  2. 修正多张图像的标准差计算逻辑:不能直接对每张图像的方差取平均再开根号,需收集所有有效像素的亮度值后统一计算整体标准差。
  3. 简化冗余操作:移除原代码中image +=1的不必要操作,直接提取有效像素无需担心黑像素误判。

修复后的完整代码

from PIL import Image, ImageDraw, ImageChops
import os
import shutil
import cv2
import numpy as np

center = (0, 0)
radius = 0
is_dragging_center = False
is_dragging_radius = False

avg_image_round = 10

def on_mouse(event, x, y, flags, param):
    global center, radius, is_dragging_center, is_dragging_radius

    if event == cv2.EVENT_LBUTTONDOWN:
        if np.sqrt((x - center[0]) ** 2 + (y - center[1]) ** 2) < 20:
            is_dragging_center = True
        else:
            is_dragging_radius = True

    elif event == cv2.EVENT_LBUTTONUP:
        is_dragging_center = False
        is_dragging_radius = False

    elif event == cv2.EVENT_MOUSEMOVE:
        if is_dragging_center:
            center = (x, y)
        elif is_dragging_radius:
            radius = int(np.sqrt((x - center[0]) ** 2 + (y - center[1]) ** 2))

def pack_data(parent_dir):
    path = os.path.join(parent_dir, "images")
    if not os.path.exists(path):
        os.mkdir(path)

    for a in os.listdir(parent_dir):
        if a.endswith(".jpg"):
            srcpath = os.path.join(parent_dir, a)
            shutil.move(srcpath, path)
    return path

def xray_count(image_path, center, radius):
    image = np.uint16(cv2.imread(image_path, cv2.IMREAD_GRAYSCALE))
    mask = np.zeros(image.shape, dtype=np.uint8)
    cv2.circle(mask, center, radius, 255, thickness=cv2.FILLED)

    # 提取mask内的有效像素
    valid_pixels = image[mask == 255]
    pixel_count = len(valid_pixels)

    if pixel_count == 0:
        avg_brightness = 0
        std_dev = 0
    else:
        avg_brightness = np.mean(valid_pixels)
        std_dev = np.std(valid_pixels)

    print(f"Image: {image_path}")
    print(f"Average brightness per pixel: {avg_brightness}")
    print(f"Standard deviation of pixels: {std_dev}")
    print("------------------------")

    return avg_brightness, valid_pixels

parent_dir = r'C:\Users\blehe\Desktop\Betatron'
path = pack_data(parent_dir)
image_files = [os.path.join(path, filename) for filename in os.listdir(path) if filename.endswith(('.jpg'))]

if not image_files:
    print("No '.jpg' files found in the input folder.")
else:
    first_image_path = image_files[0]
    image = cv2.imread(first_image_path)

    scale_percent = 40 
    width = int(image.shape[1] * scale_percent / 100)
    height = int(image.shape[0] * scale_percent / 100)
    dim = (width, height)
    resized_image = cv2.resize(image, dim, interpolation=cv2.INTER_AREA)

    center = (resized_image.shape[1] // 2, resized_image.shape[0] // 2)
    radius = min(resized_image.shape[1] // 3, resized_image.shape[0] // 3)

    cv2.namedWindow("Adjust the circle (press 'Enter' to proceed)")
    cv2.setMouseCallback("Adjust the circle (press 'Enter' to proceed)", on_mouse)

    while True:
        display_image = resized_image.copy()
        cv2.circle(display_image, center, radius, (0, 255, 0), 2)
        cv2.circle(display_image, center, 5, (0, 0, 255), thickness=cv2.FILLED)
        cv2.imshow("Adjust the circle (press 'Enter' to proceed)", display_image)

        key = cv2.waitKey(1) & 0xFF
        if key == 13:
            break

    cv2.destroyAllWindows()
                
    center = (int(center[0] / scale_percent * 100), int(center[1] / scale_percent * 100))
    radius = int(radius / scale_percent * 100)

total_brightness_sum = 0
all_valid_pixels = []
 
for i, image_path in enumerate(image_files, start=1):
    avg_brightness, valid_pixels = xray_count(image_path, center, radius)
    total_brightness_sum += avg_brightness
    all_valid_pixels.extend(valid_pixels.tolist())

    if i % avg_image_round == 0:
        # 计算n张图像的平均亮度
        avg_batch_brightness = total_brightness_sum / avg_image_round
        # 计算n张图像所有有效像素的标准差
        batch_std_dev = np.std(all_valid_pixels) if all_valid_pixels else 0

        print(f"Average Brightness for the last {avg_image_round} images: {avg_batch_brightness}")
        print(f"Standard deviation of all pixels in last {avg_image_round} images: {batch_std_dev}")
        print("------------------------")

        total_brightness_sum = 0
        all_valid_pixels = []

修复说明

  • 单张图像计算时,通过valid_pixels = image[mask == 255]直接提取感兴趣区域的像素,确保只统计有效区域,纯黑/纯白图像的标准差会正确输出0。
  • 多张图像的标准差改为收集所有有效像素后统一计算,符合统计逻辑,避免了原代码中对单张方差取平均的错误操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 11:37:02