I still new with python, and I want to print several propreties of multiple images to a csv file. I have tried How to f.write .append results to CSV but I still can't figure out where I went wrong. So, I very much appreciate your help.
Here is my code
import csv
import cv2
import glob
import numpy as np
filename1s = []
widths = []
heights = []
areas = []
rect_areas = []
equi_diameters = []
aspect_ratios = []
extents = []
solidities = []
path = 'images/*.png'
with open('file.csv','w') as f:
csv_out = csv.writer(f)
for filename1 in glob.glob(path):
imge=cv2.imread(filename1)
filename1s.append(imge)
img_maskedgray = cv2.cvtColor(imge, cv2.COLOR_BGR2GRAY)
contours2 = cv2.findContours(img_maskedgray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours2 = contours2[0] if len(contours2) == 2 else contours2[1]
big_contour2 = max(contours2, key=cv2.contourArea, default=None)
area = cv2.contourArea(big_contour2)
x,y,width,height = cv2.boundingRect(big_contour2)
aspect_ratio = float(width)/height # ratio of width to height of bounding rect of the object.
rect_area = width*height # the ratio of contour area to bounding rectangle area
extent = float(area)/rect_area
hull = cv2.convexHull(big_contour2)
hull_area = cv2.contourArea(hull)
solidity = float(area)/hull_area
equi_diameter = np.sqrt(4*area/np.pi) # diameter of the circle whose area is same as the contour area
widths.append(width)
heights.append(height)
areas.append(area)
rect_areas.append(rect_area)
equi_diameters.append(equi_diameter)
aspect_ratios.append(aspect_ratio)
extents.append(extent)
solidities.append(solidity)
csv_out.writerow([filename1, width, height, area, rect_area, equi_diameter, aspect_ratio, extent, solidity])
Thanks in advance
As stated at https://docs.python.org/3/library/csv.html if csv writter is used with file, file needs to opened with newline.
with open('file.csv','w', newline='') as f:
import csv
import cv2
import glob
import numpy as np
filename1s = []
widths = []
heights = []
areas = []
rect_areas = []
equi_diameters = []
aspect_ratios = []
extents = []
solidities = []
path = 'images/*.png'
with open('file.csv','w') as f:
csv_out = csv.writer(f)
for filename1 in glob.glob(path):
imge=cv2.imread(filename1)
filename1s.append(imge)
img_maskedgray = cv2.cvtColor(imge, cv2.COLOR_BGR2GRAY)
contours2 = cv2.findContours(img_maskedgray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours2 = contours2[0] if len(contours2) == 2 else contours2[1]
big_contour2 = max(contours2, key=cv2.contourArea, default=None)
area = cv2.contourArea(big_contour2)
x,y,width,height = cv2.boundingRect(big_contour2)
aspect_ratio = float(width)/height # ratio of width to height of bounding rect of the object.
rect_area = width*height # the ratio of contour area to bounding rectangle area
extent = float(area)/rect_area
hull = cv2.convexHull(big_contour2)
hull_area = cv2.contourArea(hull)
solidity = float(area)/hull_area
equi_diameter = np.sqrt(4*area/np.pi) # diameter of the circle whose area is same as the contour area
widths.append(width)
heights.append(height)
areas.append(area)
rect_areas.append(rect_area)
equi_diameters.append(equi_diameter)
aspect_ratios.append(aspect_ratio)
extents.append(extent)
solidities.append(solidity)
csv_out.writerow([filename1, width, height, area, rect_area, equi_diameter, aspect_ratio, extent, solidity])
Related
I am trying to extract coordinates of all features from the mediapipe library using face mesh but for every image that I am testing it's giving the same coordinates. I don't understand what's wrong here. If anyone could help, it would be great!
import mediapipe as mp
import cv2
import matplotlib.pyplot as plt
# from mpl_toolkits.mplot3d import Axes3D
import json
import os
from os import path
file_name = "./json_output"
img_base = cv2.imread("./johnny-depp-sunglasses-hat-smile-wallpaper.jpg")
img = img_base.copy()
mp_face_mesh = mp.solutions.face_mesh
face_mesh = mp_face_mesh.FaceMesh(static_image_mode=True)
results = face_mesh.process(img)
landmarks = results.multi_face_landmarks[0]
xs, ys, zs = [], [], []
CONTOUR_LIST = ["FACEMESH_LIPS", "FACEMESH_FACE_OVAL", "FACEMESH_LEFT_IRIS",
"FACEMESH_LEFT_EYEBROW","FACEMESH_LEFT_EYE", "FACEMESH_RIGHT_IRIS",
"FACEMESH_RIGHT_EYEBROW", "FACEMESH_RIGHT_EYE"]
This is the main function:
def extract_landmarks(inp):
img = img_base.copy()
for landmark in landmarks.landmark:
x = landmark.x
y = landmark.y
z = landmark.z
xs.append(x)
ys.append(y)
zs.append(z)
relative_x = int(x * img_base.shape[1])
relative_y = int(y * img_base.shape[0])
cv2.circle(img, (relative_x, relative_y),
radius=5, color=(0,0,255),
thickness=-1)
# fig = plt.figure(figsize=(15,15))
# plt.imshow(img[:,:,::-1])
# plt.show()
img = img_base.copy()
for i in inp:
for src_id, tar_id in i:
source = landmarks.landmark[src_id]
target = landmarks.landmark[tar_id]
relative_source = int(source.x * img.shape[1]), int(source.y * img.shape[0])
relative_target = int(target.x * img.shape[1]), int(target.y * img.shape[0])
cv2.line(img, relative_source, relative_target,
color=(255,255,255), thickness=2)
fig = plt.figure(figsize=(15,15))
plt.imshow(img[:,:,::-1])
plt.show()
result = inp
# print(result)
my_json = list(result)
# my_ans = [{f"{CONTOUR_LIST[k]}":{'x':x, 'y':y}} for k in range(len(CONTOUR_LIST)) for i in my_json for x,y in i]
my_ans = [{f"{CONTOUR_LIST[k]}":{'x':x, 'y':y}} for k in range(0, 8) for i in my_json for x,y in i]
#
# print(my_ans, sep="\n", end="\n")
# print("\n")
# print("\n")
# coordinates.append(my_ans)
# print(my_ans, end="\n", sep="\n")
if os.path.exists(file_name):
print("Already exists!")
# with open(file_name, 'w') as f:
# f.write(json.dumps(my_ans, indent=4, separators=(',',': ')))
else:
with open(file_name, 'w') as file:
json.dump(my_ans, file,
indent=4,
separators=(',',': '))
return len(my_json)
And this is the code for calling the function:
features = []
features.append(mp_face_mesh.FACEMESH_LIPS)
features.append(mp_face_mesh.FACEMESH_FACE_OVAL)
features.append(mp_face_mesh.FACEMESH_LEFT_IRIS)
features.append(mp_face_mesh.FACEMESH_LEFT_EYEBROW)
features.append(mp_face_mesh.FACEMESH_LEFT_EYE)
features.append(mp_face_mesh.FACEMESH_RIGHT_IRIS)
features.append(mp_face_mesh.FACEMESH_RIGHT_EYEBROW)
features.append(mp_face_mesh.FACEMESH_RIGHT_EYE)
extract_landmarks(features)
For every image, I am getting the same coordinates.
The coordinates in json_output is fixed, look at the face mesh.
The content of json_output is the numbers in the image.
relative_x and relative_y are the coordinates relative to the width and
height of the picture.
What I am trying to do is assigning every pixel value in csv file. there is 270000 pixels in every image. when i try to append the integer value, it does generate the csv file but not this integer value in the end, in this case in "kelas".
Here is my code:
import cv2 as cv
import numpy as np
import csv
import os
kelas0 = 0
kelas1 = 1
kelas2 = 2
number = []
image_list = []
tags = []
pixels = []
for i in range(0,270000):
tags.append("pixel_{}".format(i))
tags.insert(0,"index")
tags.append("kelas")
for i in range(0, 190):
number.append(i)
load_dir = "C:\\Users\\orusx\\Documents\\ITS\\TA\\Program\\dataset"
catagories = ["Kualitas A", "Kualitas B", "Kualitas C"]
with open('image_csv.csv', 'w') as f:
writer = csv.writer(f)
writer.writerow(tags)
for kelas, catagories in enumerate(os.listdir(load_dir)):
print(catagories)
for image in os.listdir(os.path.join(load_dir, catagories)):
new_path = os.path.join(load_dir,catagories)
image_list.append(os.path.join(new_path, image))
#print(image)
#print(image_list)
for index, gambar in enumerate(image_list):
print(type(index))
img = cv.imread(gambar)
img_array = list(img.flatten())
for pixel in img_array:
pixels.append(pixel)
pixels.insert(0, index)
if index <= 62:
pixels.append(kelas0)
writer.writerow(pixels)
elif 62<index<=125:
pixels.append(kelas1)
writer.writerow(pixels)
elif 125<index<=188:
pixels.append(kelas2)
writer.writerow(pixels)
pixels = []
I have a JSON file with the next structure:
json
{'featureId': 'ckek0ugf2061y0ybwgunbdrt5',
'schemaId': 'ckek0jkvp081j0yaec2ap9a3w',
'title': 'Tree',
'value': 'tree',
'color': '#FFFF00',
'instanceURI': 'https://api.labelbox.com/masks/feature/ckek0ugf2061y0ybwgunbdrt5?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'}
InstanceURI is one tree that I segmented from the original image used Labelbox (https://labelbox.com/). I am using PSPNet-cityscapes. That model requires a mask to the validation stage in png format. Some images have several trees (several instances URIs).
How can I convert this JSON element in a png image?
Not the fastest and most beautiful script - but it works for me...
from PIL import Image, ImageColor, ImageDraw
from PIL import UnidentifiedImageError
import requests
import json
import argparse
import pathlib
import os.path
def manual_classes():
"""
Change your preferenced color-coding below.
If you want to use manual coloring, you also need to change the Label-Classes (Title)
"""
manual_dict = {
'Tree': 255,
'Flower': 85,
}
return manual_dict
def open_img(url):
try:
return Image.open(requests.get(url, stream=True).raw)
except UnidentifiedImageError:
return None
def open_json(path):
with open(path) as file:
return json.load(file)
def color_extractor(data, color_coding):
"""takes the given dictionary part and extracts all needed information. returns also colors for 3 different types"""
if color_coding == 'auto':
color = ImageColor.getcolor(data['color'], 'RGBA')
elif color_coding == 'manual':
color = (manual_classes()[data['title']],manual_classes()[data['title']],manual_classes()[data['title']],255)
elif color_coding == 'binar':
color = (255,255,255,255)
else:
print('no valid color-code detected - continue with binarized Labels.')
color = (255,255,255,255)
return color
def img_color(img, color):
"""change color of label accordingly"""
if color == (255,255,255,255):
return img
img = img.convert('RGBA')
width, height = img.size
for x in range(width):
for y in range(height):
if img.getpixel((x,y)) == (255,255,255,255):
img.putpixel((x,y), color)
return img
def img_draw_polygon(size, polygon, color):
"""draw polygons on image"""
img = Image.new('RGBA', size, (0,0,0,0))
img = img.convert('RGBA')
draw = ImageDraw.Draw(img)
# read points
points = []
for i in range(len(polygon)):
points.append((int(polygon[i]['x']),int(polygon[i]['y'])))
draw.polygon(points, fill = (color))
return img
def progressBar(current, total, barLength = 20):
percent = float(current) * 100 / total
arrow = '-' * int(percent/100 * barLength - 1) + '>'
spaces = ' ' * (barLength - len(arrow))
print('Progress: [%s%s] %d %%' % (arrow, spaces, percent), end='\r')
def main(input_dir, output_dir, color_type='auto'):
if os.path.exists(input_dir) and os.path.exists(output_dir) and color_type in ['auto', 'manual', 'binar']:
input_path = pathlib.Path(input_dir)
label_paths_sorted = sorted(list(input_path.glob("*.json")))
for image_path in label_paths_sorted:
print('converting: {}'.format(os.path.basename(image_path)))
# open json file
data = open_json(image_path)
# create image list for Labels
img_list = []
# read original image
original_img = open_img(data[0]['Labeled Data'])
try:
width, height = original_img.size
except Exception:
print('Original image data not callable. Please provide image width and height.')
for i in range(len(data[0]['Label']['objects'])):
# read path and open image
img = open_img(data[0]['Label']['objects'][i]['instanceURI'])
# if path is not readable try to read polygon-data-points
if not img is None:
img = img_color(img, color_extractor(data[0]['Label']['objects'][i], color_type))
img_list.append(img)
else:
try:
# img = img_draw_polygon(img, data[0]['Label']['objects'][i]['polygon'], data[0]['Label']['objects'][i]['title'])
img = img_draw_polygon((width,height), data[0]['Label']['objects'][i]['polygon'], color_extractor(data[0]['Label']['objects'][i], color_type))
img_list.append(img)
except Exception:
print('Note: There are no available polygon-data-points & web-data-information for Label #{}.'.format(i))
# print current progress status
progressBar(i, len(data[0]['Label']['objects']))
img = img_list[0]
for i in range(1, len(img_list)):
img.paste(img_list[i], (0,0), mask= img_list[i])
img.save(output_dir + os.path.basename(image_path).replace('.json', '.png'))
else:
print('One of your given inputs is incorrect - please try again.')
if __name__ == '__main__':
parser = argparse.ArgumentParser(description="convert annotations from labelbox2png")
parser.add_argument("--input", help="input-directory")
parser.add_argument("--output", help="output-directory")
parser.add_argument("--color", help="binar, auto or manual")
args = parser.parse_args()
main(args.input, args.output, args.color)
To run it - just save this python-script and execute it in your command:
C:\Users>python script.py --input input_directory/ --output output_directory --color auto
With the input color you can modify the color-coding of your Labels. auto takes the colors from the JSON, manual you have to modify and binar white-labels everything.
I used cv2 and plt to generate images using nested loops and functions. The memory usage keep increase during the program running until the computer crash.
I tried del and gc.collection() at the end of loops and functions, but it didn't work. I want to know where is the problem?
def seg(mat_data):
data = np.array(mat_data)
signals = []
peaks = biosppy.signals.ecg.christov_segmenter(signal=data, sampling_rate = 500)[0]
for i in range(2,len(peaks)-1):
left_diff = abs(peaks[i-1]-peaks[i])//2
right_diff = abs(peaks[i+1]-peaks[i])//2
x = peaks[i]-left_diff
y = peaks[i]+right_diff
signal = data[x:y]
signals.append(signal)
return signals,peaks
def sig2img(signals,file_name,label,channel):
if label == 'null':
for i, signal in enumerate(signals):
fig = plt.figure(frameon=False)
plt.plot(signal, linewidth=3.5)
plt.xticks([]), plt.yticks([])
for spine in plt.gca().spines.values():
spine.set_visible(False)
filename = 'test_img' + '/' +file_name+'_'+str(label)+'_'+str(channel)+'_'+str(i)+'.png'
fig.savefig(filename)
plt.close(fig)
im_gray = cv2.imread(filename, cv2.IMREAD_GRAYSCALE)
im_gray = cv2.resize(im_gray, (128, 128), interpolation = cv2.INTER_LANCZOS4)
cv2.imwrite(filename, im_gray)
return
for i, signal in enumerate(signals):
fig = plt.figure(frameon=False)
plt.plot(signal, linewidth=3.5)
plt.xticks([]), plt.yticks([])
for spine in plt.gca().spines.values():
spine.set_visible(False)
filename = 'train_img' + '/' +file_name+'_'+str(label)+'_'+str(channel)+'_'+str(i)+'.png'
fig.savefig(filename)
plt.close(fig)
im_gray = cv2.imread(filename, cv2.IMREAD_GRAYSCALE)
im_gray = cv2.resize(im_gray, (128, 128), interpolation = cv2.INTER_LANCZOS4)
cv2.imwrite(filename, im_gray)
def generate_images(train = True,cut=5000):
if train == False:
data_path = 'data/test'
test_name = os.listdir(data_path)
file_raw = [(scio.loadmat(data_path+'/'+m),) for m in test_name]
data = [ normalize(d[0]['data']) for d in file_raw]
for i in range(len(test_name)):
print(test_name[i])
print(data[i].shape)
label = 'null'
for j in range(data[i].shape[0]):
print(data[i][j,:cut].shape)
signals,peaks = seg(data[i][j,:cut])
channel = j+1
sig2img(signals,test_name[i],label,channel)
data_path = 'data/train'
reference_path = 'data/reference.txt'
mat_label = pd.read_csv(reference_path,sep='\t',header = None)
mat = mat_label[0]
file_raw = [(scio.loadmat(data_path+'/'+m),) for m in mat]
train_name = [m for m in mat]
label = mat_label[1]
data = [ normalize(d[0]['data']) for d in file_raw] #data shape: 12x5000
for i in range(len(label)):
print(train_name[i])
print(data[i].shape)
print(label[i])
for j in range(data[i].shape[0]):
print(data[i][j,:cut].shape)
signals,peaks = seg(data[i][j,:cut]) #peaks is a list with length of 6~10
channel = j+1 #signals is numpy array with shape of (500,)
sig2img(signals,train_name[i],label[i],channel)
I want to know where should I add the del or gc,or some other way to free the momery during the loop running.
Simple Code used to identify playing cards through a cam but I have Been trying to run this code but I keep getting this error when attempting to use any of the methods
TypeError: src is not a numpy array, neither a scalar
import sys
import numpy as np
sys.path.insert(0, "/usr/local/lib/python2.7/site-packages/")
import cv2
###############################################################################
# Utility code
###############################################################################
def rectify(h):
h = h.reshape((4,2))
hnew = np.zeros((4,2),dtype = np.float32)
add = h.sum(1)
hnew[0] = h[np.argmin(add)]
hnew[2] = h[np.argmax(add)]
diff = np.diff(h,axis = 1)
hnew[1] = h[np.argmin(diff)]
hnew[3] = h[np.argmax(diff)]
return hnew
###############################################################################
# Image Matching
###############################################################################
def preprocess(img):
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray,(5,5),2 )
thresh = cv2.adaptiveThreshold(blur,255,1,1,11,1)
return thresh
def imgdiff(img1,img2):
img1 = cv2.GaussianBlur(img1,(5,5),5)
img2 = cv2.GaussianBlur(img2,(5,5),5)
diff = cv2.absdiff(img1,img2)
diff = cv2.GaussianBlur(diff,(5,5),5)
flag, diff = cv2.threshold(diff, 200, 255, cv2.THRESH_BINARY)
return np.sum(diff)
def find_closest_card(training,img):
features = preprocess(img)
return sorted(training.values(), key=lambda x:imgdiff(x[1],features))[0][0]
###############################################################################
# Card Extraction
###############################################################################
def getCards(im, numcards=4):
gray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray,(1,1),1000)
flag, thresh = cv2.threshold(blur, 120, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
contours = sorted(contours, key=cv2.contourArea,reverse=True)[:numcards]
for card in contours:
peri = cv2.arcLength(card,True)
approx = rectify(cv2.approxPolyDP(card,0.02*peri,True))
# box = np.int0(approx)
# cv2.drawContours(im,[box],0,(255,255,0),6)
# imx = cv2.resize(im,(1000,600))
# cv2.imshow('a',imx)
h = np.array([ [0,0],[449,0],[449,449],[0,449] ],np.float32)
transform = cv2.getPerspectiveTransform(approx,h)
warp = cv2.warpPerspective(im,transform,(450,450))
yield warp
def get_training(training_labels_filename,training_image_filename,num_training_cards,avoid_cards=None):
training = {}
labels = {}
for line in file(training_labels_filename):
key, num, suit = line.strip().split()
labels[int(key)] = (num,suit)
print "Training"
im = cv2.imread(training_image_filename)
for i,c in enumerate(getCards(im,num_training_cards)):
if avoid_cards is None or (labels[i][0] not in avoid_cards[0] and labels[i][1] not in avoid_cards[1]):
training[i] = (labels[i], preprocess(c))
print "Done training"
return training
if __name__ == '__main__':
if len(sys.argv) == 6:
filename = sys.argv[1]
num_cards = int(sys.argv[2])
training_image_filename = sys.argv[3]
training_labels_filename = sys.argv[4]
num_training_cards = int(sys.argv[5])
training = get_training(training_labels_filename,training_image_filename,num_training_cards)
im = cv2.imread("test")
width = im.shape[0]
height = im.shape[1]
if width < height:
im = cv2.transpose(im)
im = cv2.flip(im,1)
# Debug: uncomment to see registered images
#for i,c in enumerate(getCards(im,num_cards)):
# card = find_closest_card(training,c,)
# cv2.imshow(str(card),c)
# cv2.waitKey(0)
cards = [find_closest_card(training,c) for c in getCards(im,num_cards)]
print cards
else:
print __doc__
here is the entire error message
Traceback (most recent call last):
File "<pyshell#15>", line 1, in <module>
preprocess("test.JPG")
File "C:\Users\Don Ellison\Desktop\Class Programs\CSC 490 Project\Cards\Python\Playing-Card-Recognition-master\card_img.py", line 43, in preprocess
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
TypeError: src is not a numpy array, neither a scalar
you are passing in wrong argument to preprocess function, I guess you are calling it from a python shell.
You are not suppose to pass in a image file name, but rather a numpy array. It seems you called proprocess function and passed in "test.JPG" in your python shell. If you want to test your preprocess function, do
test_img = cv2.imread("test.JPG")
preprocess(test_img)