mirror of
https://github.com/opencv/opencv.git
synced 2026-07-30 07:43:03 +04:00
python: 'cv2.' -> 'cv.' via 'import cv2 as cv'
This commit is contained in:
@@ -80,7 +80,7 @@ pass in terms of square size).
|
||||
|
||||
### Setup
|
||||
|
||||
So to find pattern in chess board, we use the function, **cv2.findChessboardCorners()**. We also
|
||||
So to find pattern in chess board, we use the function, **cv.findChessboardCorners()**. We also
|
||||
need to pass what kind of pattern we are looking, like 8x8 grid, 5x5 grid etc. In this example, we
|
||||
use 7x6 grid. (Normally a chess board has 8x8 squares and 7x7 internal corners). It returns the
|
||||
corner points and retval which will be True if pattern is obtained. These corners will be placed in
|
||||
@@ -95,19 +95,19 @@ are not sure out of 14 images given, how many are good. So we read all the image
|
||||
ones.
|
||||
|
||||
@sa Instead of chess board, we can use some circular grid, but then use the function
|
||||
**cv2.findCirclesGrid()** to find the pattern. It is said that less number of images are enough when
|
||||
**cv.findCirclesGrid()** to find the pattern. It is said that less number of images are enough when
|
||||
using circular grid.
|
||||
|
||||
Once we find the corners, we can increase their accuracy using **cv2.cornerSubPix()**. We can also
|
||||
draw the pattern using **cv2.drawChessboardCorners()**. All these steps are included in below code:
|
||||
Once we find the corners, we can increase their accuracy using **cv.cornerSubPix()**. We can also
|
||||
draw the pattern using **cv.drawChessboardCorners()**. All these steps are included in below code:
|
||||
|
||||
@code{.py}
|
||||
import numpy as np
|
||||
import cv2
|
||||
import cv2 as cv
|
||||
import glob
|
||||
|
||||
# termination criteria
|
||||
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
|
||||
criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 30, 0.001)
|
||||
|
||||
# prepare object points, like (0,0,0), (1,0,0), (2,0,0) ....,(6,5,0)
|
||||
objp = np.zeros((6*7,3), np.float32)
|
||||
@@ -120,25 +120,25 @@ imgpoints = [] # 2d points in image plane.
|
||||
images = glob.glob('*.jpg')
|
||||
|
||||
for fname in images:
|
||||
img = cv2.imread(fname)
|
||||
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
|
||||
img = cv.imread(fname)
|
||||
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
|
||||
|
||||
# Find the chess board corners
|
||||
ret, corners = cv2.findChessboardCorners(gray, (7,6), None)
|
||||
ret, corners = cv.findChessboardCorners(gray, (7,6), None)
|
||||
|
||||
# If found, add object points, image points (after refining them)
|
||||
if ret == True:
|
||||
objpoints.append(objp)
|
||||
|
||||
corners2=cv2.cornerSubPix(gray,corners, (11,11), (-1,-1), criteria)
|
||||
corners2 = cv.cornerSubPix(gray,corners, (11,11), (-1,-1), criteria)
|
||||
imgpoints.append(corners)
|
||||
|
||||
# Draw and display the corners
|
||||
cv2.drawChessboardCorners(img, (7,6), corners2, ret)
|
||||
cv2.imshow('img', img)
|
||||
cv2.waitKey(500)
|
||||
cv.drawChessboardCorners(img, (7,6), corners2, ret)
|
||||
cv.imshow('img', img)
|
||||
cv.waitKey(500)
|
||||
|
||||
cv2.destroyAllWindows()
|
||||
cv.destroyAllWindows()
|
||||
@endcode
|
||||
One image with pattern drawn on it is shown below:
|
||||
|
||||
@@ -147,37 +147,37 @@ One image with pattern drawn on it is shown below:
|
||||
### Calibration
|
||||
|
||||
So now we have our object points and image points we are ready to go for calibration. For that we
|
||||
use the function, **cv2.calibrateCamera()**. It returns the camera matrix, distortion coefficients,
|
||||
use the function, **cv.calibrateCamera()**. It returns the camera matrix, distortion coefficients,
|
||||
rotation and translation vectors etc.
|
||||
@code{.py}
|
||||
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)
|
||||
ret, mtx, dist, rvecs, tvecs = cv.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)
|
||||
@endcode
|
||||
### Undistortion
|
||||
|
||||
We have got what we were trying. Now we can take an image and undistort it. OpenCV comes with two
|
||||
methods, we will see both. But before that, we can refine the camera matrix based on a free scaling
|
||||
parameter using **cv2.getOptimalNewCameraMatrix()**. If the scaling parameter alpha=0, it returns
|
||||
parameter using **cv.getOptimalNewCameraMatrix()**. If the scaling parameter alpha=0, it returns
|
||||
undistorted image with minimum unwanted pixels. So it may even remove some pixels at image corners.
|
||||
If alpha=1, all pixels are retained with some extra black images. It also returns an image ROI which
|
||||
can be used to crop the result.
|
||||
|
||||
So we take a new image (left12.jpg in this case. That is the first image in this chapter)
|
||||
@code{.py}
|
||||
img = cv2.imread('left12.jpg')
|
||||
img = cv.imread('left12.jpg')
|
||||
h, w = img.shape[:2]
|
||||
newcameramtx, roi=cv2.getOptimalNewCameraMatrix(mtx, dist, (w,h), 1, (w,h))
|
||||
newcameramtx, roi = cv.getOptimalNewCameraMatrix(mtx, dist, (w,h), 1, (w,h))
|
||||
@endcode
|
||||
#### 1. Using **cv2.undistort()**
|
||||
#### 1. Using **cv.undistort()**
|
||||
|
||||
This is the shortest path. Just call the function and use ROI obtained above to crop the result.
|
||||
@code{.py}
|
||||
# undistort
|
||||
dst = cv2.undistort(img, mtx, dist, None, newcameramtx)
|
||||
dst = cv.undistort(img, mtx, dist, None, newcameramtx)
|
||||
|
||||
# crop the image
|
||||
x, y, w, h = roi
|
||||
dst = dst[y:y+h, x:x+w]
|
||||
cv2.imwrite('calibresult.png', dst)
|
||||
cv.imwrite('calibresult.png', dst)
|
||||
@endcode
|
||||
#### 2. Using **remapping**
|
||||
|
||||
@@ -185,13 +185,13 @@ This is curved path. First find a mapping function from distorted image to undis
|
||||
use the remap function.
|
||||
@code{.py}
|
||||
# undistort
|
||||
mapx, mapy = cv2.initUndistortRectifyMap(mtx, dist, None, newcameramtx, (w,h), 5)
|
||||
dst = cv2.remap(img, mapx, mapy, cv2.INTER_LINEAR)
|
||||
mapx, mapy = cv.initUndistortRectifyMap(mtx, dist, None, newcameramtx, (w,h), 5)
|
||||
dst = cv.remap(img, mapx, mapy, cv.INTER_LINEAR)
|
||||
|
||||
# crop the image
|
||||
x, y, w, h = roi
|
||||
dst = dst[y:y+h, x:x+w]
|
||||
cv2.imwrite('calibresult.png', dst)
|
||||
cv.imwrite('calibresult.png', dst)
|
||||
@endcode
|
||||
Both the methods give the same result. See the result below:
|
||||
|
||||
@@ -207,15 +207,15 @@ Re-projection Error
|
||||
|
||||
Re-projection error gives a good estimation of just how exact is the found parameters. This should
|
||||
be as close to zero as possible. Given the intrinsic, distortion, rotation and translation matrices,
|
||||
we first transform the object point to image point using **cv2.projectPoints()**. Then we calculate
|
||||
we first transform the object point to image point using **cv.projectPoints()**. Then we calculate
|
||||
the absolute norm between what we got with our transformation and the corner finding algorithm. To
|
||||
find the average error we calculate the arithmetical mean of the errors calculate for all the
|
||||
calibration images.
|
||||
@code{.py}
|
||||
mean_error = 0
|
||||
for i in xrange(len(objpoints)):
|
||||
imgpoints2, _ = cv2.projectPoints(objpoints[i], rvecs[i], tvecs[i], mtx, dist)
|
||||
error = cv2.norm(imgpoints[i], imgpoints2, cv2.NORM_L2)/len(imgpoints2)
|
||||
imgpoints2, _ = cv.projectPoints(objpoints[i], rvecs[i], tvecs[i], mtx, dist)
|
||||
error = cv.norm(imgpoints[i], imgpoints2, cv.NORM_L2)/len(imgpoints2)
|
||||
mean_error += error
|
||||
|
||||
print( "total error: {}".format(mean_error/len(objpoints)) )
|
||||
|
||||
@@ -38,13 +38,13 @@ Code
|
||||
Below code snippet shows a simple procedure to create a disparity map.
|
||||
@code{.py}
|
||||
import numpy as np
|
||||
import cv2
|
||||
import cv2 as cv
|
||||
from matplotlib import pyplot as plt
|
||||
|
||||
imgL = cv2.imread('tsukuba_l.png',0)
|
||||
imgR = cv2.imread('tsukuba_r.png',0)
|
||||
imgL = cv.imread('tsukuba_l.png',0)
|
||||
imgR = cv.imread('tsukuba_r.png',0)
|
||||
|
||||
stereo = cv2.StereoBM_create(numDisparities=16, blockSize=15)
|
||||
stereo = cv.StereoBM_create(numDisparities=16, blockSize=15)
|
||||
disparity = stereo.compute(imgL,imgR)
|
||||
plt.imshow(disparity,'gray')
|
||||
plt.show()
|
||||
|
||||
@@ -72,14 +72,14 @@ Code
|
||||
So first we need to find as many possible matches between two images to find the fundamental matrix.
|
||||
For this, we use SIFT descriptors with FLANN based matcher and ratio test.
|
||||
@code{.py}
|
||||
import cv2
|
||||
import numpy as np
|
||||
import cv2 as cv
|
||||
from matplotlib import pyplot as plt
|
||||
|
||||
img1 = cv2.imread('myleft.jpg',0) #queryimage # left image
|
||||
img2 = cv2.imread('myright.jpg',0) #trainimage # right image
|
||||
img1 = cv.imread('myleft.jpg',0) #queryimage # left image
|
||||
img2 = cv.imread('myright.jpg',0) #trainimage # right image
|
||||
|
||||
sift = cv2.SIFT()
|
||||
sift = cv.SIFT()
|
||||
|
||||
# find the keypoints and descriptors with SIFT
|
||||
kp1, des1 = sift.detectAndCompute(img1,None)
|
||||
@@ -90,7 +90,7 @@ FLANN_INDEX_KDTREE = 1
|
||||
index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5)
|
||||
search_params = dict(checks=50)
|
||||
|
||||
flann = cv2.FlannBasedMatcher(index_params,search_params)
|
||||
flann = cv.FlannBasedMatcher(index_params,search_params)
|
||||
matches = flann.knnMatch(des1,des2,k=2)
|
||||
|
||||
good = []
|
||||
@@ -108,7 +108,7 @@ Now we have the list of best matches from both the images. Let's find the Fundam
|
||||
@code{.py}
|
||||
pts1 = np.int32(pts1)
|
||||
pts2 = np.int32(pts2)
|
||||
F, mask = cv2.findFundamentalMat(pts1,pts2,cv2.FM_LMEDS)
|
||||
F, mask = cv.findFundamentalMat(pts1,pts2,cv.FM_LMEDS)
|
||||
|
||||
# We select only inlier points
|
||||
pts1 = pts1[mask.ravel()==1]
|
||||
@@ -122,28 +122,28 @@ def drawlines(img1,img2,lines,pts1,pts2):
|
||||
''' img1 - image on which we draw the epilines for the points in img2
|
||||
lines - corresponding epilines '''
|
||||
r,c = img1.shape
|
||||
img1 = cv2.cvtColor(img1,cv2.COLOR_GRAY2BGR)
|
||||
img2 = cv2.cvtColor(img2,cv2.COLOR_GRAY2BGR)
|
||||
img1 = cv.cvtColor(img1,cv.COLOR_GRAY2BGR)
|
||||
img2 = cv.cvtColor(img2,cv.COLOR_GRAY2BGR)
|
||||
for r,pt1,pt2 in zip(lines,pts1,pts2):
|
||||
color = tuple(np.random.randint(0,255,3).tolist())
|
||||
x0,y0 = map(int, [0, -r[2]/r[1] ])
|
||||
x1,y1 = map(int, [c, -(r[2]+r[0]*c)/r[1] ])
|
||||
img1 = cv2.line(img1, (x0,y0), (x1,y1), color,1)
|
||||
img1 = cv2.circle(img1,tuple(pt1),5,color,-1)
|
||||
img2 = cv2.circle(img2,tuple(pt2),5,color,-1)
|
||||
img1 = cv.line(img1, (x0,y0), (x1,y1), color,1)
|
||||
img1 = cv.circle(img1,tuple(pt1),5,color,-1)
|
||||
img2 = cv.circle(img2,tuple(pt2),5,color,-1)
|
||||
return img1,img2
|
||||
@endcode
|
||||
Now we find the epilines in both the images and draw them.
|
||||
@code{.py}
|
||||
# Find epilines corresponding to points in right image (second image) and
|
||||
# drawing its lines on left image
|
||||
lines1 = cv2.computeCorrespondEpilines(pts2.reshape(-1,1,2), 2,F)
|
||||
lines1 = cv.computeCorrespondEpilines(pts2.reshape(-1,1,2), 2,F)
|
||||
lines1 = lines1.reshape(-1,3)
|
||||
img5,img6 = drawlines(img1,img2,lines1,pts1,pts2)
|
||||
|
||||
# Find epilines corresponding to points in left image (first image) and
|
||||
# drawing its lines on right image
|
||||
lines2 = cv2.computeCorrespondEpilines(pts1.reshape(-1,1,2), 1,F)
|
||||
lines2 = cv.computeCorrespondEpilines(pts1.reshape(-1,1,2), 1,F)
|
||||
lines2 = lines2.reshape(-1,3)
|
||||
img3,img4 = drawlines(img2,img1,lines2,pts2,pts1)
|
||||
|
||||
|
||||
@@ -24,8 +24,8 @@ should feel like it is perpendicular to our chessboard plane.
|
||||
First, let's load the camera matrix and distortion coefficients from the previous calibration
|
||||
result.
|
||||
@code{.py}
|
||||
import cv2
|
||||
import numpy as np
|
||||
import cv2 as cv
|
||||
import glob
|
||||
|
||||
# Load previously saved data
|
||||
@@ -33,13 +33,13 @@ with np.load('B.npz') as X:
|
||||
mtx, dist, _, _ = [X[i] for i in ('mtx','dist','rvecs','tvecs')]
|
||||
@endcode
|
||||
Now let's create a function, draw which takes the corners in the chessboard (obtained using
|
||||
**cv2.findChessboardCorners()**) and **axis points** to draw a 3D axis.
|
||||
**cv.findChessboardCorners()**) and **axis points** to draw a 3D axis.
|
||||
@code{.py}
|
||||
def draw(img, corners, imgpts):
|
||||
corner = tuple(corners[0].ravel())
|
||||
img = cv2.line(img, corner, tuple(imgpts[0].ravel()), (255,0,0), 5)
|
||||
img = cv2.line(img, corner, tuple(imgpts[1].ravel()), (0,255,0), 5)
|
||||
img = cv2.line(img, corner, tuple(imgpts[2].ravel()), (0,0,255), 5)
|
||||
img = cv.line(img, corner, tuple(imgpts[0].ravel()), (255,0,0), 5)
|
||||
img = cv.line(img, corner, tuple(imgpts[1].ravel()), (0,255,0), 5)
|
||||
img = cv.line(img, corner, tuple(imgpts[2].ravel()), (0,0,255), 5)
|
||||
return img
|
||||
@endcode
|
||||
Then as in previous case, we create termination criteria, object points (3D points of corners in
|
||||
@@ -48,7 +48,7 @@ of length 3 (units will be in terms of chess square size since we calibrated bas
|
||||
our X axis is drawn from (0,0,0) to (3,0,0), so for Y axis. For Z axis, it is drawn from (0,0,0) to
|
||||
(0,0,-3). Negative denotes it is drawn towards the camera.
|
||||
@code{.py}
|
||||
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
|
||||
criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 30, 0.001)
|
||||
objp = np.zeros((6*7,3), np.float32)
|
||||
objp[:,:2] = np.mgrid[0:7,0:6].T.reshape(-1,2)
|
||||
|
||||
@@ -56,32 +56,32 @@ axis = np.float32([[3,0,0], [0,3,0], [0,0,-3]]).reshape(-1,3)
|
||||
@endcode
|
||||
Now, as usual, we load each image. Search for 7x6 grid. If found, we refine it with subcorner
|
||||
pixels. Then to calculate the rotation and translation, we use the function,
|
||||
**cv2.solvePnPRansac()**. Once we those transformation matrices, we use them to project our **axis
|
||||
**cv.solvePnPRansac()**. Once we those transformation matrices, we use them to project our **axis
|
||||
points** to the image plane. In simple words, we find the points on image plane corresponding to
|
||||
each of (3,0,0),(0,3,0),(0,0,3) in 3D space. Once we get them, we draw lines from the first corner
|
||||
to each of these points using our draw() function. Done !!!
|
||||
@code{.py}
|
||||
for fname in glob.glob('left*.jpg'):
|
||||
img = cv2.imread(fname)
|
||||
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
|
||||
ret, corners = cv2.findChessboardCorners(gray, (7,6),None)
|
||||
img = cv.imread(fname)
|
||||
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
|
||||
ret, corners = cv.findChessboardCorners(gray, (7,6),None)
|
||||
|
||||
if ret == True:
|
||||
corners2 = cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria)
|
||||
corners2 = cv.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria)
|
||||
|
||||
# Find the rotation and translation vectors.
|
||||
ret,rvecs, tvecs, inliers = cv2.solvePnP(objp, corners2, mtx, dist)
|
||||
ret,rvecs, tvecs, inliers = cv.solvePnP(objp, corners2, mtx, dist)
|
||||
|
||||
# project 3D points to image plane
|
||||
imgpts, jac = cv2.projectPoints(axis, rvecs, tvecs, mtx, dist)
|
||||
imgpts, jac = cv.projectPoints(axis, rvecs, tvecs, mtx, dist)
|
||||
|
||||
img = draw(img,corners2,imgpts)
|
||||
cv2.imshow('img',img)
|
||||
k = cv2.waitKey(0) & 0xFF
|
||||
cv.imshow('img',img)
|
||||
k = cv.waitKey(0) & 0xFF
|
||||
if k == ord('s'):
|
||||
cv2.imwrite(fname[:6]+'.png', img)
|
||||
cv.imwrite(fname[:6]+'.png', img)
|
||||
|
||||
cv2.destroyAllWindows()
|
||||
cv.destroyAllWindows()
|
||||
@endcode
|
||||
See some results below. Notice that each axis is 3 squares long.:
|
||||
|
||||
@@ -97,14 +97,14 @@ def draw(img, corners, imgpts):
|
||||
imgpts = np.int32(imgpts).reshape(-1,2)
|
||||
|
||||
# draw ground floor in green
|
||||
img = cv2.drawContours(img, [imgpts[:4]],-1,(0,255,0),-3)
|
||||
img = cv.drawContours(img, [imgpts[:4]],-1,(0,255,0),-3)
|
||||
|
||||
# draw pillars in blue color
|
||||
for i,j in zip(range(4),range(4,8)):
|
||||
img = cv2.line(img, tuple(imgpts[i]), tuple(imgpts[j]),(255),3)
|
||||
img = cv.line(img, tuple(imgpts[i]), tuple(imgpts[j]),(255),3)
|
||||
|
||||
# draw top layer in red color
|
||||
img = cv2.drawContours(img, [imgpts[4:]],-1,(0,0,255),3)
|
||||
img = cv.drawContours(img, [imgpts[4:]],-1,(0,0,255),3)
|
||||
|
||||
return img
|
||||
@endcode
|
||||
|
||||
Reference in New Issue
Block a user