Python обработка изображений в циклах for с выходом в CSV - PullRequest
0 голосов
/ 27 мая 2020

Недавно я задал несколько вопросов и скомпилировал кучу различных субкодов, которые отлично работают. Я подошел к концу своих знаний о Python / программировании. Первая часть - это код, который берет имена файлов из файла .csv и сопоставляет их с изображениями в папке для l oop. Если изображение имеет совпадение, код сегментирует изображение, находит контуры и их центральные координаты и записывает их в список.

Ниже приведен код для этой первой части:

import csv
import numpy as np
import os
import cv2
import imutils

#color definition
red_lower = np.array([160,210,230])
red_upper = np.array([180,255,255])

#contour size filter
s1 = 500
s2 = 10000

#create empty lists for contour center coordinates
x = []
y = []

#open csv file with filtered times, loop through rows
#and check if the file exists to prevent errors

with open('test_input_filenames.csv','rb') as csvfile:
    reader = csv.reader(csvfile, delimiter = ',')
    next(reader)    #skip the first row, it contains column names
    for row in reader:
        filename = ','.join(row) + '.jpg'
        print filename
        img = cv2.imread(filename)
        #apply median blur, 15 means it's smoothing image 15x15 pixels
        blur = cv2.medianBlur(img,15)
        #convert to hsv
        hsv = cv2.cvtColor(blur, cv2.COLOR_BGR2HSV)
        #red color mask (sort of thresholding, actually segmentation)
        mask = cv2.inRange(hsv, red_lower, red_upper)
        #copy image for, .findContours distorts the source image
        mask_copy = mask.copy()
        #find contours
        cnts = cv2.findContours(mask_copy,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
        #extract contours from the list??
        cnts = imutils.grab_contours(cnts)
        #loop through contours and filter out the ones of specific size
        #looping is for contour center and radius calculation
        #all contour center coordinates get filled in the x and y lists
        for cnt in cnts:
            area = cv2.contourArea(cnt)
            moment = cv2.moments(cnt)
            if s1<area<s2:
                print area
                c_x = int(moment["m10"]/moment["m00"])
                c_y = int(moment["m01"]/moment["m00"])
                x.append(c_x)
                y.append(c_y)
                print (c_x, c_y)



        cv2.namedWindow('image', cv2.WINDOW_NORMAL)
        cv2.imshow('image', mask)
cv2.waitKey(0) & 0xFF

print x
print y

Вторая часть - это код, который загружает изображение, сегментирует его, находит контуры, вычисляет координаты и помещает их в список . Этот список затем используется для расчета радиусов изгиба для этих контуров (радиусов больше, потому что я пытаюсь увидеть, как они меняются с течением времени - это необходимо для проверки деформации ограничителя изгиба шланга). Эти радиусы затем заполняются списком и помещаются в файл .csv.

Ниже приведен код для второй части:

import cv2
import numpy as np
import scipy
from matplotlib import pyplot as plt
import imutils
import csv

#load image
img = cv2.imread('dot5_red.jpg')

#apply median blur, 15 means it's smoothing image 15x15 pixels
blur = cv2.medianBlur(img,15)

#convert to hsv
hsv = cv2.cvtColor(blur, cv2.COLOR_BGR2HSV)

#color definition
red_lower = np.array([160,210,230])
red_upper = np.array([180,255,255])

#red color mask (sort of thresholding, actually segmentation)
mask = cv2.inRange(hsv, red_lower, red_upper)

#copy image for, .findContours distorts the source image
mask_copy = mask.copy()

#find contours
cnts = cv2.findContours(mask_copy,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)

#extract contours from the list??
cnts = imutils.grab_contours(cnts)

#contour size filter
s1 = 500
s2 = 10000

#define lists for x and y coordinates of contour centers
#note that you call values from the list starting with 0
x = []
y = []

#calculate center coord and display data
#x.append needs the float definition, otherwise all values in
#list are integers
for cnt in cnts:
    area = cv2.contourArea(cnt)
    moment = cv2.moments(cnt)
    if s1<area<s2:
        print area
        c_x = int(moment["m10"]/moment["m00"])
        c_y = int(moment["m01"]/moment["m00"])
        x.append(float(c_x))
        y.append(float(c_y))
        print (c_x, c_y)

#create empty list to fill with bend radiuses
r_b = []        


#for loop for looping through the points and calculating bend radius
#loop starts with value 1 because we skip the first value in list x[0]


for i in range(1,len(x)-1):
    print i

    k_p0 = ((y[i] - y[i-1])/(x[i] - x[i-1]))
    k_t0 = (-1/k_p0)
    k_p1 = ((y[i+1] - y[i])/(x[i+1] - x[i]))
    k_t1 = (-1/k_p1)
    n_t0 = (y[i-1] - k_t0 * x[i-i])
    n_t1 = (y[i] - k_t1 * x[i])

    x_TT = ((n_t1 - n_t0)/(k_t0 - k_t1))
    y_TT = k_t0 * x_TT + n_t0

    r = np.sqrt((y[i] - y_TT)**2 + (x[i] - x_TT)**2)
    r_b.append(float(r))

    print r

print r_b

#new loop to fill the output csv file with results row-by-row
with open('image_radius_output1.csv','wb') as out_file:
    writer = csv.writer(out_file)
    writer.writerow(r_b)
out_file.close()

Моя цель - объединить эти два кода так, чтобы изображения в папке будут сопоставлены с именами файлов во входном файле .csv, если совпадение положительное, изображение будет обработано (сегментация, контуры, координаты центра контура, радиусы изгиба), а результаты радиусов будут записаны в файл .csv . Это должно быть oop до конца входного файла .csv, а результаты должны быть записаны в выходной файл .csv с новой строкой для каждого изображения.

Сильфон - это пример формы выходного файла.

output .csv:

image,radius1,radius2,radius3,radius4,radius5
image1,radius1_value,radius2_value,radius3_value,radius4_value,radius5_value
image2,radius1_value,radius2_value,radius3_value,radius4_value,radius5_value
image3,radius1_value,radius2_value,radius3_value,radius4_value,radius5_value
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...