Вывод неправильных хначений минимального и максимального лимита красного

Программа состоит из функций draw_freeform(event, x, y, flags, param)-для рисования участка семечки, def analyze_masked_area(image, mask)- для применения маски выделенной области, find_max_row(numb_matrix)- поиска длинны семечки, find_max_column(numb_matrix)- поиск ширины семечки, main()-основная функция.При запуске программы выходит окно в котором выделяю границы семечки, затем нажимаю клавишу q. Создаётся csv файл и повёрнутое изображение.В csv файле в столбец LimitRedMin записаны значения (lineС,0), а в LimitRedMax содержатся (lineC, widthSeed). Подскажите, что не так в программе. введите сюда описание изображения

Код прилагается:

import csv
import numpy as np
from PIL import Image
import cv2
import math


def main():
    global drawing, mask, temp_image, image
    drawing = False  # Левый клик мыши нажат
    mask = None  # Маска для выделенной области
    image = None  # Оригинальное изображение
    path = '774-3.jpg'
    image = cv2.imread(path)
    if image is None:
        raise FileNotFoundError(f"Изображение {path} не найдено.")

    # Инициализация маски
    mask = np.zeros(image.shape[:2], dtype=np.uint8)
    temp_image = image.copy()
    print(image.size)  # Для определения размера изображения
    # Создание окна для рисования
    cv2.namedWindow("Выделение области")
    cv2.setMouseCallback("Выделение области", draw_freeform)
    cv2.imshow("Выделение области", image)

    # Ожидание завершения выделения
    print("Рисуйте область свободной формы, затем нажмите 'q', чтобы продолжить.")
    while True:
        key = cv2.waitKey(1) & 0xFF
        if key == ord('q'):  # Нажмите 'q' для завершения
            break

    cv2.destroyAllWindows()

    # Анализ выделенной области
    if np.any(mask > 0):
        max_r, max_g, max_b, min_r, min_g, min_b = analyze_masked_area(image, mask)
        print(f"Максимальные значения в выделенной области:\nR: {max_r}, G: {max_g}, B: {max_b}")
        print(f"Минимальные значения в выделенной области:\nR: {min_r}, G: {min_g}, B: {min_b}")
    else:
        print("Выделенная область не обнаружена.")

    image = Image.open(path)
    angle315 = image.rotate(325)
    img315 = angle315.crop((170, 178, 1227, 790))
    img315.save('774-3-rotate.jpg')
    img = cv2.imread('774-3-rotate.jpg')
    print(image.size)  # Для определения размера изображения

    r, g, b = cv2.split(img)
    # Укажите диапазоны для каждого канала

    # Создаём бинарную матрицу на основе диапазонов для всех каналов
    bitMatrix = ((r >= min_r) & (r <= max_r) &
                 (g >= min_g) & (g <= max_g) &
                 (b >= min_b) & (b <= max_b))
    numb_matrix = bitMatrix.astype(int)

    max_row_coordinates, max_col_coordinates = find_coordinates(numb_matrix)

    min_r = min(max_row_coordinates)
    max_r = max(max_row_coordinates)
    max_c = max(max_col_coordinates)
    min_c = min(max_col_coordinates)

    x_min_r_coordinate = min_r[0]
    y_min_r_coordinate = min_r[1]
    x_max_r_coordinate = max_r[0]
    y_max_r_coordinate = max_r[1]
    x_min_c_coordinate = min_c[0]
    y_min_c_coordinate = min_c[1]
    x_max_c_coordinate = max_c[0]
    y_max_c_coordinate = max_c[1]

    L_1 = [[x_min_r_coordinate, y_min_r_coordinate],
           [x_max_r_coordinate, y_max_r_coordinate]]
    L_2 = [[x_min_c_coordinate, y_min_c_coordinate],
           [x_max_c_coordinate, y_max_c_coordinate]]

    xd = (L_1[0][0] - L_1[1][0], L_2[0][0] - L_2[1][0])
    yd = (L_1[0][1] - L_1[1][1], L_2[0][1] - L_2[1][1])
    div = xd[0] * yd[1] - xd[1] * yd[0]
    if div == 0:
        raise Exception('lines do not intersect')
    d = (L_1[0][0] * L_1[1][1] - L_1[0][1] * L_1[1][0], L_2[0][0] * L_2[1][1] - L_2[0][1] * L_2[1][0])
    x = (d[0] * xd[1] - d[1] * xd[0]) / div
    y = (d[0] * yd[1] - d[1] * yd[0]) / div

    lineA = int(y - y_min_r_coordinate)
    lineB = int(y_max_r_coordinate - y)
    lineC = int(x - x_min_c_coordinate)
    lineD = int(x_max_c_coordinate - x)

    square = numb_matrix.sum()

    widthSeed = lineA + lineB
    heightSeed = lineC + lineD

    with open('774-3-rotate.csv', 'w', newline='') as f:
        fieldnames = ['Name', 'lineA', 'lineB', 'lineC', 'lineD', 'square', 'heightSeed', 'widthSeed',
                      'LimitRedMin', 'LimitRedMax', "LimitGreenMin", "LimitGreenMax", "LimitBlueMin", "LimitBlueMax"]
        writer = csv.DictWriter(f, fieldnames=fieldnames, delimiter=';')
        writer.writeheader()
        writer.writerow({'Name': path, 'lineA': lineA, 'lineB': lineB, 'lineC': lineC, 'lineD': lineD,
                         'square': square, 'heightSeed': heightSeed, 'widthSeed': widthSeed,
                         'LimitRedMin': min_r, 'LimitRedMax': max_r,
                         "LimitGreenMin": min_g, "LimitGreenMax": max_g,
                         "LimitBlueMin": min_b, "LimitBlueMax": max_b})


# Функция обратного вызова для рисования
def draw_freeform(event, x, y, flags, param):
    global drawing, mask, temp_image

    if event == cv2.EVENT_LBUTTONDOWN:  # Начало рисования
        drawing = True
        cv2.circle(mask, (x, y), 5, 255, -1)  # Радиус кисти
        cv2.circle(temp_image, (x, y), 5, (0, 255, 0), -1)

    elif event == cv2.EVENT_MOUSEMOVE and drawing:  # Рисование при движении мыши
        cv2.circle(mask, (x, y), 5, 255, -1)
        cv2.circle(temp_image, (x, y), 5, (0, 255, 0), -1)

    elif event == cv2.EVENT_LBUTTONUP:  # Завершение рисования
        drawing = False
        cv2.circle(mask, (x, y), 5, 255, -1)
        cv2.circle(temp_image, (x, y), 5, (0, 255, 0), -1)


def analyze_masked_area(image, mask):
    # Применение маски для выделенной области
    selected_pixels = cv2.bitwise_and(image, image, mask=mask)

    # Извлечение каналов R, G и B
    b_channel, g_channel, r_channel = cv2.split(selected_pixels)

    # Удаление нулевых значений для поиска минимума и максимума
    r_values = r_channel[mask > 0]
    g_values = g_channel[mask > 0]
    b_values = b_channel[mask > 0]

    # Вычисление максимальных и минимальных значений
    max_r = np.max(r_values) if len(r_values) > 0 else 0
    min_r = np.min(r_values) if len(r_values) > 0 else 0

    max_g = np.max(g_values) if len(g_values) > 0 else 0
    min_g = np.min(g_values) if len(g_values) > 0 else 0

    max_b = np.max(b_values) if len(b_values) > 0 else 0
    min_b = np.min(b_values) if len(b_values) > 0 else 0

    return max_r, max_g, max_b, min_r, min_g, min_b


def find_max_row(numb_matrix):
    max_sum = 0
    max_row_index = -1
    for i, row in enumerate(numb_matrix):
        row_sum = sum(row)
        if row_sum > max_sum:
            max_sum = row_sum
            max_row_index = i
    return max_row_index


def find_max_column(numb_matrix):
    max_sum = 0
    max_col_index = -1
    for j in range(len(numb_matrix[0])):
        col_sum = sum(numb_matrix[i][j] for i in range(len(numb_matrix)))
        if col_sum > max_sum:
            max_sum = col_sum
            max_col_index = j
    return max_col_index


def find_coordinates(numb_matrix):
    max_row_index = find_max_row(numb_matrix)
    max_col_index = find_max_column(numb_matrix)

    max_row = numb_matrix[max_row_index]
    max_col = [numb_matrix[i][max_col_index] for i in range(len(numb_matrix))]

    max_row_ones = [i for i, val in enumerate(max_row) if val == 1]
    max_col_ones = [i for i, val in enumerate(max_col) if val == 1]

    return [(max_row_index, col) for col in max_row_ones], [(row, max_col_index) for row in max_col_ones]


if __name__ == '__main__':
    main()

Ответы (1 шт):

Автор решения: Денис Гурков

Подозреваю, что ошибка в этих двух строчках

min_r = min(max_row_coordinates)
max_r = max(max_row_coordinates)

Вы видимо хотели объявить две новые переменные, обозначающие минимальный и максимальный номер строки, но вместо этого перезаписали ранее объявленные

max_r, max_g, max_b, min_r, min_g, min_b = analyze_masked_area(image, mask)
→ Ссылка