Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
hackassin
GitHub Repository: hackassin/learnopencv
Path: blob/master/AugmentedRealityWithArucoMarkers/augmented_reality_with_aruco.py
3092 views
1
# This code is written by Sunita Nayak at BigVision LLC. It is based on the OpenCV project. It is subject to the license terms in the LICENSE file found in this distribution and at http://opencv.org/license.html
2
3
# Usage example: python3 augmented_reality_with_aruco.py --image=test.jpg
4
# python3 augmented_reality_with_aruco.py --video=test.mp4
5
6
import cv2 as cv
7
#from cv2 import aruco
8
import argparse
9
import sys
10
import os.path
11
import numpy as np
12
13
parser = argparse.ArgumentParser(description='Augmented Reality using Aruco markers in OpenCV')
14
parser.add_argument('--image', help='Path to image file.')
15
parser.add_argument('--video', help='Path to video file.')
16
args = parser.parse_args()
17
18
im_src = cv.imread("new_scenery.jpg");
19
20
outputFile = "ar_out_py.avi"
21
if (args.image):
22
# Open the image file
23
if not os.path.isfile(args.image):
24
print("Input image file ", args.image, " doesn't exist")
25
sys.exit(1)
26
cap = cv.VideoCapture(args.image)
27
outputFile = args.image[:-4]+'_ar_out_py.jpg'
28
elif (args.video):
29
# Open the video file
30
if not os.path.isfile(args.video):
31
print("Input video file ", args.video, " doesn't exist")
32
sys.exit(1)
33
cap = cv.VideoCapture(args.video)
34
outputFile = args.video[:-4]+'_ar_out_py.avi'
35
print("Storing it as :", outputFile)
36
else:
37
# Webcam input
38
cap = cv.VideoCapture(0)
39
40
# Get the video writer initialized to save the output video
41
if (not args.image):
42
vid_writer = cv.VideoWriter(outputFile, cv.VideoWriter_fourcc('M','J','P','G'), 28, (round(2*cap.get(cv.CAP_PROP_FRAME_WIDTH)),round(cap.get(cv.CAP_PROP_FRAME_HEIGHT))))
43
44
winName = "Augmented Reality using Aruco markers in OpenCV"
45
46
while cv.waitKey(1) < 0:
47
try:
48
# get frame from the video
49
hasFrame, frame = cap.read()
50
51
# Stop the program if reached end of video
52
if not hasFrame:
53
print("Done processing !!!")
54
print("Output file is stored as ", outputFile)
55
cv.waitKey(3000)
56
break
57
58
#Load the dictionary that was used to generate the markers.
59
dictionary = cv.aruco.Dictionary_get(cv.aruco.DICT_6X6_250)
60
61
# Initialize the detector parameters using default values
62
parameters = cv.aruco.DetectorParameters_create()
63
64
# Detect the markers in the image
65
markerCorners, markerIds, rejectedCandidates = cv.aruco.detectMarkers(frame, dictionary, parameters=parameters)
66
67
index = np.squeeze(np.where(markerIds==25));
68
refPt1 = np.squeeze(markerCorners[index[0]])[1];
69
70
index = np.squeeze(np.where(markerIds==33));
71
refPt2 = np.squeeze(markerCorners[index[0]])[2];
72
73
distance = np.linalg.norm(refPt1-refPt2);
74
75
scalingFac = 0.02;
76
pts_dst = [[refPt1[0] - round(scalingFac*distance), refPt1[1] - round(scalingFac*distance)]];
77
pts_dst = pts_dst + [[refPt2[0] + round(scalingFac*distance), refPt2[1] - round(scalingFac*distance)]];
78
79
index = np.squeeze(np.where(markerIds==30));
80
refPt3 = np.squeeze(markerCorners[index[0]])[0];
81
pts_dst = pts_dst + [[refPt3[0] + round(scalingFac*distance), refPt3[1] + round(scalingFac*distance)]];
82
83
index = np.squeeze(np.where(markerIds==23));
84
refPt4 = np.squeeze(markerCorners[index[0]])[0];
85
pts_dst = pts_dst + [[refPt4[0] - round(scalingFac*distance), refPt4[1] + round(scalingFac*distance)]];
86
87
pts_src = [[0,0], [im_src.shape[1], 0], [im_src.shape[1], im_src.shape[0]], [0, im_src.shape[0]]];
88
89
pts_src_m = np.asarray(pts_src)
90
pts_dst_m = np.asarray(pts_dst)
91
92
# Calculate Homography
93
h, status = cv.findHomography(pts_src_m, pts_dst_m)
94
95
# Warp source image to destination based on homography
96
warped_image = cv.warpPerspective(im_src, h, (frame.shape[1],frame.shape[0]))
97
98
# Prepare a mask representing region to copy from the warped image into the original frame.
99
mask = np.zeros([frame.shape[0], frame.shape[1]], dtype=np.uint8);
100
cv.fillConvexPoly(mask, np.int32([pts_dst_m]), (255, 255, 255), cv.LINE_AA);
101
102
# Erode the mask to not copy the boundary effects from the warping
103
element = cv.getStructuringElement(cv.MORPH_RECT, (3,3));
104
mask = cv.erode(mask, element, iterations=3);
105
106
# Copy the mask into 3 channels.
107
warped_image = warped_image.astype(float)
108
mask3 = np.zeros_like(warped_image)
109
for i in range(0, 3):
110
mask3[:,:,i] = mask/255
111
112
# Copy the warped image into the original frame in the mask region.
113
warped_image_masked = cv.multiply(warped_image, mask3)
114
frame_masked = cv.multiply(frame.astype(float), 1-mask3)
115
im_out = cv.add(warped_image_masked, frame_masked)
116
117
# Showing the original image and the new output image side by side
118
concatenatedOutput = cv.hconcat([frame.astype(float), im_out]);
119
cv.imshow("AR using Aruco markers", concatenatedOutput.astype(np.uint8))
120
121
# Write the frame with the detection boxes
122
if (args.image):
123
cv.imwrite(outputFile, concatenatedOutput.astype(np.uint8));
124
else:
125
vid_writer.write(concatenatedOutput.astype(np.uint8))
126
127
128
except Exception as inst:
129
print(inst)
130
131
cv.destroyAllWindows()
132
if 'vid_writer' in locals():
133
vid_writer.release()
134
print('Video writer released..')
135
136