Не выводит в csv файл метрические характеристики семечек
Сначала программа поворачивает изображение обрезает и сохраняет в цикле набор изображений в цикле в папку output_folder. Потом идёт циклическая обработка изображений этой папки-создаётся набор матриц с 0 и 1 где на пикселе r,g,b<115,115,115 там 1, а в противном случаи 0. Далее нахождение сумм столбцов матриц и находить максимальные по сумме их столбцы в цикле.Также их индексы аналогичные действия необходимо проводить и с строками матриц.В строках с максимальными суммами находить минимальные и максимальные значения индексов столбцов со значениями матрицы 1. и аналогические действия проводятся со столбцами. По кординатам окраин длин и ширин изображений находим точки их пересечения. Потом нужно высчитать части длинн и части ширин до и точек их пересечениях.
Далее необходимо найти характеристики формы указанные внизу программы. Изображения семечек прилагаются [![семечка из директории SeedsBela][1]][1] [![семечка из директории SeedsBela][2]] [2] [![семечка из директории SeedsBela][3]][3] [![семечка из директории SeedsBela][4]][4]
Код:
import csv
import numpy as np
from PIL import Image # Подключим необходимые библиотеки.
import cv2
import math
import time
import os
from multiprocessing.pool import Pool
def main():
input_folder = "SeedsBela"
output_folder = "RotateCropImages"
# Создаем выходную папку, если ее еще нет
if not os.path.exists(output_folder):
os.makedirs(output_folder)
# Получаем список файлов в папке с изображениями
image_files = [f for f in os.listdir(input_folder) if f.endswith(('.png', '.jpg', '.jpeg'))]
# Указываем угол поворота и обрезку
rotation_angle = 315
crop_box = (250, 188, 1248, 883) # (left, top, right, bottom)
for image_file in image_files:
input_path = os.path.join(input_folder, image_file)
output_path = os.path.join(output_folder, image_file)
# Открываем изображение
with Image.open(input_path) as img:
# Поворачиваем изображение
rotated_img = img.rotate(rotation_angle)
# Обрезаем изображение
cropped_img = rotated_img.crop(crop_box)
# Сохраняем результат
cropped_img.save(output_path)
tp1 = time.time()
images = []
for filename in os.listdir(output_folder):
file_path = os.path.abspath(os.path.join(output_folder, filename))
if os.path.isfile(file_path):
images.append(file_path)
p = Pool(processes=4)
results = p.map(process_image, images)
p.close()
p.join()
tp2 = time.time()
print(f'*** Общее время: {tp2 - tp1} ***')
def process_image(path):
print(f'*** Изображение: {path} ***')
# ----------------------------------------
# Строки 41 - 47. Преобразование фотографии в матрицу нулей и едениц
image = cv2.imread(path)
r, g, b = cv2.split(image)
bit_matrix_r = (r < 115)
bit_matrix_g = (g < 115)
bit_matrix_b = (b < 115)
bit_matrix = np.multiply(np.multiply(bit_matrix_r, bit_matrix_g), bit_matrix_b)
numb_matrix = bit_matrix.astype(int)
for row in numb_matrix:
# row Переменная для хранения
# максимальной суммы строки.
max_row = 0
# Переменная для хранения
# индекса строки с максимальной суммой.
id_row = 0
# индекс текущей строки
i = 0
# для каждой строки в матрице ...
# сумму элементов переданного ей списка.
# Если сумма элементов строки
# больше значения max_row,
if sum(row) > max_row: # Функция sum() возвращает
# то присвоить переменной max_row эту сумму,
max_row = sum(row)
# а в id_row сохранить индекс этой строки.
id_row = i
# увеличить индекс на 1
i += 1
# Переменная для хранения
# максимальной суммы столбца.
max_col = 0
# Переменная для хранения
# индекса столбца с максимальной суммой.
id_col = 0
# перебор индексов столбцов
for i in range(len(numb_matrix)):
# сумма текущего столбца
col_sum = 0
# перебор индексов строк
for j in range(len(numb_matrix)):
# Извлекается очередной элемент столбца,
# и добавляется к col_sum,
# при этом изменяется индекс строк (j),
# индекс столбца неизменен (i).
col_sum += numb_matrix[j][i]
# Если сумма элементов текущего столбца
# больше значения max_col,
if col_sum > max_col:
# то записать значение
# первой переменной в вторую,
max_col = col_sum
# а индекс столбца сохранить в id_col.
id_col = i
# вывод индекса столбца и его суммы
#print(id_col, '-', max_col)
height_s = sum(numb_matrix[id_col]) # Ширина семечки
width_s = sum(numb_matrix[id_row]) # Длинна семечки
stroka = np.array(numb_matrix[id_row])#Значения матрицы по ширине семечки
stolbec = np.array(numb_matrix[id_col])#Значения матрицы по длинне семечки
for i in range(len(stroka)): # Столбцы строки с максимальной суммой со значением 1
if (stroka[i] == 1):
index_stroka_element = np.array(i) # Вывод номеров столбцов строки с максимальной суммой со значением 1
for i in range(len(stolbec)): # Строки столбца с максимальной суммой со значением 1
if (stolbec[i] == 1):
index_stolbec_element = np.array(i) # Преобразование в массив номеров строк столбца с максимальной суммой со значением 1
max_X = + index_stroka_element # Максимальная координата Y строки с максимальной суммой
max_Y = + index_stolbec_element # Максимальная координата X столбца с максимальной суммой
min_x = max_X - width_s + 1 # Минимальная координата Y строки с максимальной суммой
min_y = max_Y - height_s # Минимальная координата X столбца с максимальной суммой
L_1 = [[id_row, min_x], [id_row, max_X]] # Координаты начала и конца линии по длинне семечки
L_2 = [[min_y, id_col], [max_Y, id_col]] # Координаты начала и конца линии по ширине семечки
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 # Кооордината пересечения по x
y = (d[0] * yd[1] - d[1] * yd[0]) / div # Кооордината пересечения по y
lineA = y - min_x # Часть ширина семечки до центра
lineB = max_X - y # Часть ширины от центра до края
lineC = max_X - x # Часть длины семечки до центра
lineD = x - min_y # Часть длины семечки от центра к краю
rs1 = lineA * lineC / 2 # Площадь 1 трикутника
rs2 = lineC * lineB / 2 # Площадь 2 трикутника
rs3 = lineA * lineD / 2 # Площадь 3 трикутника
rs4 = lineB * lineD / 2 # Площадь 4 трикутника
romb = rs1 + rs2 + rs3 + rs4 # Площадь ромба ,состоящего из этих треугольников
R_Proportion1 = rs1 / romb# Часть площади в 1 секторе
R_Proportion2 = rs2 / romb# Часть площади в 2 секторе
R_Proportion3 = rs3 / romb# Часть площади в 3 секторе
R_Proportion4 = rs4 / romb# Часть площади в 4 секторе
square = 0
for i in range(len(numb_matrix)):
for j in range(len(numb_matrix[i])):
square += numb_matrix[i][j]#Площадь всего изображения семечки
square1 = square * R_Proportion1# Площадь 1-го сектора семечки
square2 = square * R_Proportion2# Площадь 2-го сектора семечки
square3 = square * R_Proportion3# Площадь 3-го сектора семечки
square4 = square * R_Proportion4# Площадь 4-го сектора семечки
S_Dug1 = rs1 - square1# Площадь 1-го сектора семечки вне треугольнитка
S_Dug2 = rs2 - square2# Площадь 2-го сектора семечки вне треугольнитка
S_Dug3 = rs3 - square3# Площадь 3-го сектора семечки вне треугольнитка
S_Dug4 = rs4 - square4# Площадь 4-го сектора семечки вне треугольнитка
hip1 = math.sqrt(lineA ** 2 + lineC ** 2)#Гипотенуза 1 треугольника
hip2 = math.sqrt(lineC ** 2 + lineB ** 2)#Гипотенуза 2 треугольника
hip3 = math.sqrt(lineA ** 2 + lineD ** 2)#Гипотенуза 3 треугольника
hip4 = math.sqrt(lineB ** 2 + lineD ** 2)#Гипотенуза 4 треугольника
beta1 = math.asin(lineC / hip1)# Первал половина 1 угла
beta2 = math.asin(lineC / hip2)# Первал половина 3 угла
beta3 = math.asin(lineD / hip3)# Вторая половина 3 угла
beta4 = math.asin(lineD / hip4)# Вторая половина 1 угла
alpha1 = 90 - beta1# Первал половина 2 угла
alpha2 = 90 - beta2# Первал половина 4 угла
alpha3 = 90 - beta3# Вторая половина 4 угла
alpha4 = 90 - beta4# Вторая половина 2 угла
firstAngle = beta1 + beta4#Первый угол
secondAngle = alpha1 + alpha2#Второй укол
thirdAngle = beta2 + beta3#Третий угол
fourthAngle = alpha1 + alpha4#Четвёртый угол
zol = (lineA + lineB) / (lineC + lineD)#Отношения длинны и ширины
with open('BlackSeedsBelka.csv', 'w', newline='') as f:
fieldnames = ['Name', 'lineA', 'lineB', 'lineC', 'lineD', 'firstAngle', 'secondAngle', 'thirdAngle',
'fourthAngle',
'square', 'S_Dug1', 'S_Dug2', 'S_Dug3', 'S_Dug4', 'zol']
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
writer.writerow({'Name': path, 'lineA': lineA, 'lineB': lineB, 'lineC': lineC, 'lineD': lineD,
'firstAngle': firstAngle, 'secondAngle': secondAngle, 'thirdAngle': thirdAngle,
'fourthAngle': fourthAngle, 'square': square, 'S_Dug1': S_Dug1, 'S_Dug2': S_Dug2,
'S_Dug3': S_Dug3,
'S_Dug4': S_Dug4, 'zol': zol})
if __name__ == '__main__':
main()
Результат работы программы:
multiprocessing.pool.RemoteTraceback: """ Traceback (most recent call last): File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.7_3.7.2544.0_x64__qbz5n2kfra8p0\lib\multiprocessing\pool.py", line 121, in worker result = (True, func(*args, **kwds)) File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.7_3.7.2544.0_x64__qbz5n2kfra8p0\lib\multiprocessing\pool.py", line 44, in mapstar return list(map(*args)) File "E:\CentrCicleImages\main.py", line 136, in process_image xd = (L_1[0][0] - L_1[1][0], L_2[0][0] - L_2[1][0]) UnboundLocalError: local variable 'L_1' referenced before assignment """
The above exception was the direct cause of the following exception:
Traceback (most recent call last): File "E:\CentrCicleImages\main.py", line 206, in main() File "E:\CentrCicleImages\main.py", line 50, in main results = p.map(process_image, images) File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.7_3.7.2544.0_x64__qbz5n2kfra8p0\lib\multiprocessing\pool.py", line 268, in map return self._map_async(func, iterable, mapstar, chunksize).get() File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.7_3.7.2544.0_x64__qbz5n2kfra8p0\lib\multiprocessing\pool.py", line 657, in get raise self._value UnboundLocalError: local variable 'L_1' referenced before assignment
Process finished with exit code 1