获取多张图像的总平均亮度偏差

Getting the total mean brightness deviation of multiple images

提问人:Niandra Lades 提问时间:11/15/2023 最后编辑:Niandra Lades 更新时间:11/15/2023 访问量:38

问:

我正在使用相机并获取图像进行分析。我正在尝试获取以下信息:

  1. 获取每张图片的平均亮度和亮度标准偏差
  2. 获取每 n 张图片的平均亮度和亮度标准差

我的代码拍摄了一张图像,让用户选择一个感兴趣的区域进行分析。当我在预期偏差为零的纯黑白图像上测试代码时,我得到了意想不到的值。我很难理解我的代码在标准偏差计算方面的不足之处,因为亮度工作得很好。

谁能帮我找到我的错误?谢谢!

法典:

from PIL import Image, ImageDraw, ImageChops
import os
from datetime import datetime
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
count = 0
count += 1

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

    if event == cv2.EVENT_LBUTTONDOWN:
        # Check if the mouse click is near the center
        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):
    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)

    image += 1  # Avoid not counting black pixels in image
    result = cv2.bitwise_and(image, image, mask=mask)

    pixel_count = np.count_nonzero(result)

    brightness_sum = np.sum(result)
    var = (np.std(result))** 2

    avg_brightness = (brightness_sum / pixel_count) - 1 if pixel_count > 0 else 0  # Subtracting back

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

    return avg_brightness, var

parent_dir = r'C:\Users\blehe\Desktop\Betatron'
path = pack_data(parent_dir, r"C:\Users\blehe\Desktop\Betatron")
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)

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

    # Create a window and set the mouse callback function
    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:  # 'Enter' key
            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
total_var = 0
 
for i, image_path in enumerate(image_files, start=1):
    avg_brightness, var = xray_count(image_path, center, radius)
    total_brightness_sum += avg_brightness
    total_var += var

    if i % avg_image_round == 0:
        num_files = i 
        print(f"Average Brightness for the last {avg_image_round} images: {total_brightness_sum / avg_image_round}")
        print(f"Average standard deviation: {np.sqrt(total_var / avg_image_round)}")
        print("------------------------")

        total_brightness_sum = 0
        total_var = 0

Python 图像处理 统计信息

评论

0赞 Mark Setchell 11/15/2023
我猜你意识到JPEG是有损的,看起来黑色的东西可能不是完全为零 - 事实上它们可能相当大。
0赞 Niandra Lades 11/15/2023
我该如何检查是否是这种情况?当我在可能松散的黑色图像上运行程序时,我得到每张图片和每 n 张图片的平均亮度为零,这是一个好兆头。平均亮度是否有效,但标准偏差无效?
0赞 Niandra Lades 11/16/2023
更新:舍入误差是由于 + - 1 用于计算图像中的黑色像素。有没有人比我更清楚如何以不同的方式计算黑色像素?

答: 暂无答案