Related
i want to build 3d scanner with stereo camera and LED Projector. I calibrated the stereo camera and created the mechanical system. I project gray code and capture them with two camera. I decoded the images and take correspondence image. But i can't triangulate the decoded points. This is my reference project for generate pattern and decode them.
Reference Github project
And this is my code
import numpy as np
import cv2
import structuredlight as sl
def generate_rectify_data(calib_data, size):
XML_File = cv2.FileStorage(calib_data, cv2.FILE_STORAGE_READ)
M1 = XML_File.getNode('Camera_Matrix_Left').mat()
M2 = XML_File.getNode('Camera_Matrix_Right').mat()
d1 = XML_File.getNode('Camera_Distortion_Left').mat()
d2 = XML_File.getNode('Camera_Distortion_Right').mat()
R = XML_File.getNode('Rotation_Matrix').mat()
t = XML_File.getNode('Translation_Matrix').mat()
flag = cv2.CALIB_ZERO_DISPARITY
R1, R2, P1, P2, Q = cv2.stereoRectify(cameraMatrix1=M1, cameraMatrix2=M2,
distCoeffs1=d1, distCoeffs2=d2, R=R, T=t, flags=flag, alpha=-1, imageSize=size,
newImageSize=size)[0:5]
map_x_l, map_y_l = cv2.initUndistortRectifyMap(M1, d1, R1, P1, size, cv2.CV_32FC1)
map_x_r, map_y_r = cv2.initUndistortRectifyMap(M2, d2, R2, P2, size, cv2.CV_32FC1)
return map_x_l, map_y_l, map_x_r, map_y_r, P1, P2,Q
def rectify(img, map_x, map_y):
res = cv2.remap(img, map_x, map_y, cv2.INTER_LINEAR, cv2.BORDER_CONSTANT)
return res
"""
***I generate pattern like this and capture them in another python script***
W = 240
H = 240
gray = sl.Gray()
imlist_posi_x_pat = gray.generate((W, H))
imlist_posi_y_pat = sl.transpose(gray.generate((H, W)))
"""
if __name__ == '__main__':
img_size = (1648, 1232)
map_x_l, map_y_l, map_x_r, map_y_r, P1, P2, Q = generate_rectify_data(
"C:/Users/XXX/PycharmProjects/Stereo_Structured_Light/Calibration_Data"
"/Calibration_Parameters_1.xml", size=(1648, 1232))
rect_list_l, rect_list_r = [], []
imlist_posi_x_cap_R = []
imlist_posi_y_cap_R = []
imlist_posi_x_cap_L = []
imlist_posi_y_cap_L = []
for i in range(0,16):
img_l = cv2.imread("C:/OxO_Scan/Images_1/Left_cam3/L_" + str(i) + ".png", 0)
img_r = cv2.imread("C:/OxO_Scan/Images_1/Right_cam3/R_" + str(i) + ".png", 0)
l_rect = rectify(img_l, map_x_l, map_y_l)
r_rect = rectify(img_r, map_x_r, map_y_r)
if i < 8: # 8 for the horizontal, 8 for the vertical pattern images
imlist_posi_x_cap_R.append(r_rect)
imlist_posi_x_cap_L.append(l_rect)
else:
imlist_posi_y_cap_R.append(r_rect)
imlist_posi_y_cap_L.append(l_rect)
W = 240
H = 240
gray = sl.Gray()
img_index_x_R = gray.decode(imlist_posi_x_cap_R, thresh=40)
img_index_x_L = gray.decode(imlist_posi_x_cap_L, thresh=40)
img_index_y_R = gray.decode(imlist_posi_y_cap_R, thresh=40)
img_index_y_L = gray.decode(imlist_posi_y_cap_L, thresh=40)
img_correspondence_x_r = cv2.merge([0.0 * np.zeros_like(img_index_x_R),
img_index_x_R / W, img_index_y_R / H])
img_correspondence_r = np.clip(img_correspondence_x_r * 255.0, 0,
255).astype(np.uint8)
img_correspondence_y_l = cv2.merge([0.0 * np.zeros_like(img_index_x_L),
img_index_x_L / W, img_index_y_L / H])
img_correspondence_l = np.clip(img_correspondence_y_l * 255.0, 0,
255).astype(np.uint8)
####################################
cv2.imshow("a", cv2.resize(img_correspondence_l, (640, 480)))
cv2.imshow("b", cv2.resize(img_correspondence_r, (640, 480)))
cv2.waitKey()
cv2.destroyAllWindows()
img_correspondence_L_2 = np.copy(img_correspondence_l)
img_correspondence_R_2 = np.copy(img_correspondence_r)
cam_pts_l, cam_pts_r = [], []
cam_pts_l2, cam_pts_r2 = [], []
for i in range(img_correspondence_l.shape[0]):
for j in range(img_correspondence_l.shape[1]):
if (img_correspondence_l[i][j] != 0).any():
qwert = img_index_x_L[i][j]
cam_pts_l.append([j, i])
cam_pts_r.append([j+qwert, i])
cam_pts_l = np.array(cam_pts_l, dtype=np.float32)
cam_pts_r = np.array(cam_pts_r, dtype=np.float32)
cam_pts_l = np.array(cam_pts_l)[:, np.newaxis, :]
cam_pts_r = np.array(cam_pts_r)[:, np.newaxis, :]
pts4D = cv2.triangulatePoints(P1, P2, np.float32(cam_pts_l),np.float32(cam_pts_r)).T
pts3D = (pts4D[:, :3] / pts4D[:, -1:])
I don't know what to do in code for loop "for i in range(img_correspondence_l.shape[0]):" For example, I cannot find where a point that I found using left correspondence image in the left camera image corresponds to in the right camera image. j+img_index_x_L[i][j] does not give correct results. What should i do here
Thanks for your answers
I want to calculate variance, gabor and entropy filters to some images, but the images have blank areas that I donĀ“t want to apply the filters. I try to use a np.ma.array option but return this error: "'MaskedArray' object is not callable"
this is the code:
def bandas_img (image, array1, array2):
imagenRGB = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
return cv2.inRange(imagenRGB, array1, array2)
def rescale_by_width(image, target_width, method=cv2.INTER_LANCZOS4):
h = int(round(target_width * image.shape[0] / image.shape[1]))
return cv2.resize(image, (target_width, h), interpolation=method)
#Resized image by width
target_width = 400
#To mask null values
mask_image = True
hue = 20
sat = 57
value = 116
toleranciaH = 150
toleranciaS = 150
toleranciaV = 150
lower = np.array ([hue - toleranciaH, sat - toleranciaS, value - toleranciaV])
upper = np.array ([hue + toleranciaH, sat + toleranciaS, value + toleranciaV])
#working directory where the csv files are
os.chdir("C:/Users/Mariano/Documents/3 - Visual studio code/Prueba filtrar mascara/filtrada") ##ojoooo las barras van /// y no D:/OMAN/BHI TEXTURES/U-2
file_extension = '.png' #Check Extension
all_filenames = [i for i in glob.glob(f"*{file_extension}")]
for f in all_filenames:
image = cv2.imread(f,1)
#resized Image
resized1 = rescale_by_width(image, target_width)
#Set f value (image name)
f = f.replace(".png", "")
#Save Image
plt.imsave(f+"_resized.png", resized1)
#Create mask for null values
if mask_image == True:
mask = bandas_img(resized1, lower, upper)
cv2.imwrite(f+"_mask.png", mask)
resized2 = io.imread(f+"_resized.png", as_gray=True)
resized3 = resized2.copy()
#First Try
resized3[mask == 0] = np.nan
resized3[mask != 0] = resized2[mask != 0]
#Second Try
mask1 = (resized3 == np.nan)
resized_Mask = np.ma.array(resized3, mask = mask1)
#Varianza
k=6
img_mean = ndimage.uniform_filter(resized_Mask, (k, k))
img_sqr_mean = ndimage.uniform_filter(resized_Mask**2, (k, k))
img_var = img_sqr_mean - img_mean**2
img_var[mask == 0] = 1
plt.imsave(f+"_varianza.png", img_var)
I was tasked to create a football players detection using OpenCV (4.5.5) and python and found a problem where my notebook is returning these error codes but I am not knowledgeable enough in python and openCV to fix this:
<ipython-input-12-4322b53719b8> in <module>
19
20 net.setInput(blob)
---> 21 outs = net.forward(output_layers)
22 outs = get_players(outs, height, width)
23 for i in range(len(outs)):
error: OpenCV(4.5.5) :-1: error: (-5:Bad argument) in function 'forward'
> Overload resolution failed:
> - Can't convert object to 'str' for 'outputName'
> - Can't parse 'outputBlobs'. Input argument doesn't provide sequence protocol
> - Can't parse 'outputBlobs'. Input argument doesn't provide sequence protocol
> - Can't parse 'outBlobNames'. Input argument doesn't provide sequence protocol
> - Can't parse 'outBlobNames'. Input argument doesn't provide sequence protocol
OpenCV(4.5.5) :-1: error: (-5:Bad argument) in function 'forward'
> Overload resolution failed:
> - Can't convert object to 'str' for 'outputName'
> - Can't parse 'outputBlobs'. Input argument doesn't provide sequence protocol
> - Can't parse 'outputBlobs'. Input argument doesn't provide sequence protocol
> - Can't parse 'outBlobNames'. Input argument doesn't provide sequence protocol
> - Can't parse 'outBlobNames'. Input argument doesn't provide sequence protocol
Here's my full code that i'm running, need some guidance to resolve this issue or perhaps anyone has done a football video analysis using openCV and python. Thanks.
import numpy as np
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.models import load_model
from numpy import argmax
model = load_model(r'C:/Users/Benjamin Tiopan/players-matching/files/model.h5')
cap = cv2.VideoCapture(r'C:/Users/Benjamin Tiopan/players-matching/data/video.avi')
temp=cv2.imread(r'C:/Users/Benjamin Tiopan/players-matching/data/temp.jpg',0)
ground=cv2.imread(r'C:/Users/Benjamin Tiopan/players-matching/data/dst.jpg')
wt, ht = temp.shape[::-1]
frame_width = int(cap.get(3))
frame_height = int(cap.get(4))
#if you want to write video
out = cv2.VideoWriter('match.avi',cv2.VideoWriter_fourcc('M','J','P','G'), 20, (1920,1080))
out2 = cv2.VideoWriter('plane.avi',cv2.VideoWriter_fourcc('M','J','P','G'), 20, (900,600))
if (cap.isOpened()== False):
print("Error opening video stream or file")
# Load Yolo
net = cv2.dnn.readNet('C:/Users/Benjamin Tiopan/players-matching/files/yolov3.weights', 'C:/Users/Benjamin Tiopan/players-matching/files/yolov3.cfg')
classes = []
with open('C:/Users/Benjamin Tiopan/players-matching/files/coco.names', "r") as f:
classes = [line.strip() for line in f.readlines()]
layer_names = net.getLayerNames()
output_layers = (layer_names[i[0] - 1] for i in net.getUnconnectedOutLayers())
colors = np.random.uniform(0, 255, size=(len(classes), 3))
def plane(players,ball):
coptemp=ground.copy()
matrix=np.array([[ 2.56945407e-01, 5.90910632e-01, 1.94094537e+02],
[-1.33508274e-02, 1.37658562e+00, -8.34967286e+01],
[-3.41878940e-05, 1.31509536e-03, 1.00000000e+00]])
for p in players:
x=p[0]+int(p[2]/2)
y=p[1]+p[3]
pts3 = np.float32([[x,y]])
pts3o=cv2.perspectiveTransform(pts3[None, :, :],matrix)
x1=int(pts3o[0][0][0])
y1=int(pts3o[0][0][1])
pp=(x1,y1)
if(p[4]==0):
cv2.circle(coptemp,pp, 15, (255,0,0),-1)
elif p[4]==1:
cv2.circle(coptemp,pp, 15, (255,255,255),-1)
elif p[4]==2:
#print hakm
#cv2.circle(coptemp,pp, 15, (0,0,255),-1)
pass
if len(ball) !=0:
xb=ball[0]+int(ball[2]/2)
yb=ball[1]+int(ball[3]/2)
pts3ball = np.float32([[xb,yb]])
pts3b=cv2.perspectiveTransform(pts3ball[None, :, :],matrix)
x2=int(pts3b[0][0][0])
y2=int(pts3b[0][0][1])
pb=(x2,y2)
cv2.circle(coptemp,pb, 15, (0,0,0),-1)
return coptemp
def get_players(outs,height, width):
class_ids = []
confidences = []
boxes = []
players=[]
for out in outs:
for detection in out:
scores = detection[5:]
class_id = np.argmax(scores)
confidence = scores[class_id]
if confidence > 0.5:
# Object detected
center_x = int(detection[0] * width)
center_y = int(detection[1] * height)
w = int(detection[2] * width)
h = int(detection[3] * height)
# Rectangle coordinates
x = int(center_x - w / 2)
y = int(center_y - h / 2)
boxes.append([x, y, w, h])
confidences.append(float(confidence))
class_ids.append(class_id)
indexes = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.4)
for i in range(len(boxes)):
if i in indexes:
x, y, w, h = boxes[i]
label = str(classes[class_ids[i]])
if label=='person':
players.append(boxes[i])
return players
opr=0
while(cap.isOpened()):
ret, frame = cap.read()
players=[]
ball=[]
if opr<310:
opr=opr+1
continue
if ret == True :
copy=frame.copy()
gray= cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
height, width, channels = frame.shape
blob = cv2.dnn.blobFromImage(frame, 0.00392, (416, 416), (0, 0, 0), True, crop=False)
net.setInput(blob)
outs = net.forward(output_layers)
outs = get_players(outs, height, width)
for i in range(len(outs)):
x, y, w, h = outs[i]
roi = frame[y:y+h,x:x+w]
#some frames are bad so resize function throw an error
try:
roi=cv2.resize(roi, (96,96))
except:
continue
ym=model.predict(np.reshape(roi,(1,96,96,3)))
ym=argmax(ym)
players.append([x,y,w,h,ym])
if ym==0:
cv2.rectangle(copy, (x, y), (x + w, y + h), (0,0,255), 2)
elif ym==1:
cv2.rectangle(copy, (x, y), (x + w, y + h), (0,255,0), 2)
elif ym==2:
cv2.rectangle(copy, (x, y), (x + w, y + h), (255,0,0), 2)
res = cv2.matchTemplate(gray,temp,cv2.TM_SQDIFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
if min_val < 0.05:
top_left = min_loc
bottom_right = (top_left[0] + wt, top_left[1] + ht)
ball.append(top_left[0])
ball.append(top_left[1])
ball.append(wt)
ball.append(ht)
cv2.rectangle(copy,top_left, bottom_right, (0,255,100), 2)
p=plane(players, ball)
out.write(copy)
out2.write(p)
cv2.imshow('img',copy)
cv2.imshow('plane',p)
# this will run the video without stop and maybe the cv2 window will stop between every frame
# depending on your pc power ( i recommend to use (opencv with gpu) and colab to run script quickly )
# if you want script stop between every frame and manually you allow the script to continue change it t ocv2.waitKey(0)
if cv2.waitKey(1)==27:
break
# When everything done, release the video capture object
cap.release()
out.release()
out2.release()
# Closes all the frames
cv2.destroyAllWindows()
i used this code below to extract patches from a image.
extract code:
import os
import glob
from PIL import Image
Image.MAX_IMAGE_PIXELS = None # to avoid image size warning
imgdir = "/path/to/image/folder"
filelist = [f for f in glob.glob(imgdir + "**/*.png", recursive=True)]
savedir = "/path/to/image/folder/output"
start_pos = start_x, start_y = (0, 0)
cropped_image_size = w, h = (256, 256)
for file in filelist:
img = Image.open(file)
width, height = img.size
frame_num = 1
for col_i in range(0, width, w):
for row_i in range(0, height, h):
crop = img.crop((col_i, row_i, col_i + w, row_i + h))
name = os.path.basename(file)
name = os.path.splitext(name)[0]
save_to= os.path.join(savedir, name+"_{:03}.png")
crop.save(save_to.format(frame_num))
frame_num += 1
Now i want to reconstruct this imagem from all those patches extracted before, i've tried 2 diffenret codes
so my DB is 120x256x256x3 extracted patches, theres 120 patches to fit in 3840x2048 shape..:
patches = []
for directory_path in glob.glob('D:\join_exemplo'):
for img_path in glob.glob(os.path.join(directory_path, "*.png")):
img = cv2.imread(img_path,1)
patches.append(img)
input_patches = np.array(patches)
first i've tried sklearn.feature_extraction.image importing reconstruct_from_patches_2d, but got a black image:
reconstruct = reconstruct_from_patches_2d(input_patches, input_image)
reconstruct = reconstruct.astype(np.uint8)
Image.fromarray(reconstruct, 'RGB').save(r'D:\join_exemplo\re\re3.png')
also tried, this below but got a grayscale tone pattern image
input_image = (3840,2048,3)
reconstructed_arr = np.zeros(shape=(3840,2048,3))
#%%
>>> step = 256
>>> for x in range(img.shape[0]):
for y in range(img.shape[1]):
x_pos, y_pos = x * step, y * step
reconstructed_arr[x_pos:x_pos + 512, y_pos:y_pos + 512] = img[x, y, 0, ...]
>>> (input_image == reconstructed_arr).all()
True
cv2.imwrite(r'D:\join_exemplo\re\re.png',reconstructed_arr)
Can someone see whats wrong? sorry about my bad english
I have a folder of images and I want to crop them in a circular shape.
This is the original image:
The result that I want is this:
My code is:
import os
import glob
from PIL import Image, ImageDraw, ImageFilter
import numpy as np
def mask_circle_solid(pil_img, background_color, blur_radius, offset=0):
background = Image.new(pil_img.mode, pil_img.size, background_color)
offset = blur_radius * 2 + offset
mask = Image.new("L", pil_img.size, 0)
draw = ImageDraw.Draw(mask)
draw.ellipse((offset, offset, pil_img.size[0] - offset, pil_img.size[1] - offset), fill=255)
mask = mask.filter(ImageFilter.GaussianBlur(blur_radius))
return Image.composite(pil_img, background, mask)
def mask_circle_transparent(pil_img, blur_radius, offset=0):
offset = blur_radius * 2 + offset
mask = Image.new("L", pil_img.size, 0)
draw = ImageDraw.Draw(mask)
draw.ellipse((offset, offset, pil_img.size[0] - offset, pil_img.size[1] - offset), fill=255)
mask = mask.filter(ImageFilter.GaussianBlur(blur_radius))
result = pil_img.copy()
result.putalpha(mask)
return result
def crop_max_square(pil_img):
return crop_center(pil_img, min(pil_img.size), min(pil_img.size))
def crop_center(pil_img, crop_width, crop_height):
img_width, img_height = pil_img.size
return pil_img.crop(((img_width - crop_width) // 2,
(img_height - crop_height) // 2,
(img_width + crop_width) // 2,
(img_height + crop_height) // 2))
im = []
for f in glob.iglob("./*.jpg"):
im.append(np.asarray(Image.open(f)))
thumb_width = 150
im = np.array(im)
list_files = os.listdir(".")
list_files.sort()
list_files.remove("Test.py")
list_files.remove(".DS_Store")
for i in range(0,len(im)):
im_square[i] = crop_max_square(im[i]).resize((thumb_width, thumb_width), Image.LANCZOS)
im_thumb[i] = mask_circle_transparent(im_square[i], 4)
im_thumb[i].save(list_files[i])
I have used the functions from this article:
Generate square or circular thumbnail images with Python, Pillow
But I get this error:
line 30, in crop_max_square
return crop_center(pil_img, min(pil_img.size), min(pil_img.size))
TypeError: 'int' object is not iterable
I'm not sure if you really need to use numpy to load the files, but you can do what the "Sample code for batch processing" of the page you shared does:
import os
import glob
from PIL import Image, ImageDraw, ImageFilter
def mask_circle_solid(pil_img, background_color, blur_radius, offset=0):
background = Image.new(pil_img.mode, pil_img.size, background_color)
offset = blur_radius * 2 + offset
mask = Image.new("L", pil_img.size, 0)
draw = ImageDraw.Draw(mask)
draw.ellipse((offset, offset, pil_img.size[0] - offset, pil_img.size[1] - offset), fill=255)
mask = mask.filter(ImageFilter.GaussianBlur(blur_radius))
return Image.composite(pil_img, background, mask)
def mask_circle_transparent(pil_img, blur_radius, offset=0):
offset = blur_radius * 2 + offset
mask = Image.new("L", pil_img.size, 0)
draw = ImageDraw.Draw(mask)
draw.ellipse((offset, offset, pil_img.size[0] - offset, pil_img.size[1] - offset), fill=255)
mask = mask.filter(ImageFilter.GaussianBlur(blur_radius))
result = pil_img.copy()
result.putalpha(mask)
return result
def crop_max_square(pil_img):
return crop_center(pil_img, min(pil_img.size), min(pil_img.size))
def crop_center(pil_img, crop_width, crop_height):
img_width, img_height = pil_img.size
return pil_img.crop(((img_width - crop_width) // 2,
(img_height - crop_height) // 2,
(img_width + crop_width) // 2,
(img_height + crop_height) // 2))
im = []
jpgs_files_path = "./" # Replace the "./" path by the path where the .jpg images are.
files = glob.glob(os.path.join(jpgs_files_path, '*.jpg'))
thumb_width = 150
for f in files:
im = Image.open(f)
im_thumb = crop_max_square(im).resize((thumb_width, thumb_width), Image.LANCZOS)
im_thumb = mask_circle_transparent(im_thumb, 4)
ftitle, fext = os.path.splitext(os.path.basename(f))
im_thumb.save(os.path.join("./dstdir/", ftitle + '_thumbnail.png'), quality=95)
As JPG does not support transparency you need to discard the Alpha Channel or save as something that supports transparency like PNG.