Вывод неправильных хначений минимального и максимального лимита красного
Программа состоит из функций 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)