I'm trying to Stitching image wide angle 160.5 degree but the result is not a good
i'm using OpenCV 4 and ffmpeg to get frames from video
ffmpeg command to get 15 frame per sec :
ffmpeg -i first.mp4 -vf fps=15 preview%05d.jpg
OpenCV Stitching code
import cv2
import numpy as np
images = []
for i in range(70):
name = ('preview%05d.jpg' % (i+1))
print(name)
images.append(cv2.imread(name , cv2.IMREAD_COLOR))
print("start ")
stitcher = cv2.Stitcher_create()
ret, pano = stitcher.stitch(images)
if ret == cv2.STITCHER_OK:
cv2.imshow('panorama', pano)
cv2.waitKey()
cv2.destroyAllWindows()
else:
print(cv2.STITCHER_ERR_NEED_MORE_IMGS)
print(cv2.STITCHER_ERR_HOMOGRAPHY_EST_FAIL)
print(cv2.STITCHER_ERR_CAMERA_PARAMS_ADJUST_FAIL)
print(ret)
print('Error during stiching')
actual result :
expected result :
Before the code line stitcher = cv2.Stitcher_create()
you have to append some more algorithms that transform your trapezoid image view into a rectangle image view via the homography method.
use: cv2.findHomography(srcPoints, dstPoints[, method[, ransacReprojThreshold[, mask]]])
See also here for findHomography
at OpenCV.
In particular: in your case the base (bottom side of the image) shows most information whereas topside has more non relevant information. Here you should keep the aspect ratio topside the same and narrow the bottom. This should be done for every image. Once done you can try stitching them again.
Approach example to transform Trapezium based image information in e.g. square image:
(information ratio x)
----+++++++---- (1)
---+++++++++--- (1)
--+++++++++++-- (1)
-+++++++++++++- (1)
+++++++++++++++ (1)
into Squared image information:
(information ratio x)
----+++++++---- (1)
----+++++++---- (1.1)
----+++++++---- (1.2)
----+++++++---- (1.3)
----+++++++---- (1.4; most compressed information ratio)
Once this is done you can stitch it. Don't forget to post the result ;-)
Another approach is to treat the camera as a line-inspector. This method you use when you take information from each image for lets say line y1060 to 1080 (e.g. image size 1920x1080px) and then fill a new array with the information from those 20 lines in ascending order.
Update Jan 2019:
As homography appears not to do 100% the job due to the steep 60 degree angle you can try to correct the angle by performing the PerspectiveTransform
first.
# you can add a for-loop + image counter here to perform action on all images taken from
# the movie-file. Then its easily replacing numbers in the next part for the name
# of the image.
scr_array = [] # source e.g. pts1 = np.float32([[56,65],[368,52],[28,387],[389,390]])
dest_array = [] # destination e.g. pts2 = np.float32([[0,0],[300,0],[0,300],[300,300]])
Matrix1 = cv2.getPerspectiveTransform(scr_array,dest_array)
dst = cv2.warpPerspective(image, Matrix1 , (cols, rows))
label = 'CarImage1' # use ('CarImage%s' % labelnr) here for automated annotation.
# cv2.imshow(label , dst) # check the image
# cv2.imwrite(('%s.jpg' % label), dst)
See also the docs here on PerspectiveTransform.