def _get_corners(img, board, refine = True, checkerboard_flags=0):
"""
Get corners for a particular chessboard for an image
"""
h = img.shape[0]
w = img.shape[1]
if len(img.shape) == 3 and img.shape[2] == 3:
mono = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
else:
mono = img
(ok, corners) = cv2.findChessboardCorners(mono, (board.n_cols, board.n_rows), flags = cv2.CALIB_CB_ADAPTIVE_THRESH |
cv2.CALIB_CB_NORMALIZE_IMAGE | checkerboard_flags)
if not ok:
return (ok, corners)
# If any corners are within BORDER pixels of the screen edge, reject the detection by setting ok to false
# NOTE: This may cause problems with very low-resolution cameras, where 8 pixels is a non-negligible fraction
# of the image size. See http://answers.ros.org/question/3155/how-can-i-calibrate-low-resolution-cameras
BORDER = 8
if not all([(BORDER < corners[i, 0, 0] < (w - BORDER)) and (BORDER < corners[i, 0, 1] < (h - BORDER)) for i in range(corners.shape[0])]):
ok = False
if refine and ok:
# Use a radius of half the minimum distance between corners. This should be large enough to snap to the
# correct corner, but not so large as to include a wrong corner in the search window.
min_distance = float("inf")
for row in range(board.n_rows):
for col in range(board.n_cols - 1):
index = row*board.n_rows + col
min_distance = min(min_distance, _pdist(corners[index, 0], corners[index + 1, 0]))
for row in range(board.n_rows - 1):
for col in range(board.n_cols):
index = row*board.n_rows + col
min_distance = min(min_distance, _pdist(corners[index, 0], corners[index + board.n_cols, 0]))
radius = int(math.ceil(min_distance * 0.5))
cv2.cornerSubPix(mono, corners, (radius,radius), (-1,-1),
( cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.1 ))
return (ok, corners)
python类CALIB_CB_ADAPTIVE_THRESH的实例源码
def _findChessboard(self):
# Find the chess board corners
flags = cv2.CALIB_CB_FAST_CHECK
if self._detect_sensible:
flags = (cv2.CALIB_CB_FAST_CHECK |
cv2.CALIB_CB_ADAPTIVE_THRESH |
cv2.CALIB_CB_FILTER_QUADS |
cv2.CALIB_CB_NORMALIZE_IMAGE)
(didFindCorners, corners) = cv2.findChessboardCorners(
self.img, self.opts['size'], flags=flags
)
if didFindCorners:
# further refine corners, corners is updatd in place
cv2.cornerSubPix(self.img, corners, (11, 11), (-1, -1),
# termination criteria for corner estimation for
# chessboard method
(cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER,
30, 0.001)
) # returns None
return didFindCorners, corners
def detect_corners(self):
self.parent.app.setOverrideCursor(qt.QCursor(qt.Qt.WaitCursor))
self.chessboard_status = []
self.chessboard_points_2D = [np.zeros([ (self.chessboard_squares_x.value() - 1)*(self.chessboard_squares_y.value() - 1),2]) for i in range(len(self.images))]
self.n_chessboard_points = (self.chessboard_squares_x.value() - 1, self.chessboard_squares_y.value() - 1 )
for imnum in range(len(self.images)):
self.status_text.setText('<b>Detecting chessboard pattern in image {:d} / {:d}...</b>'.format(imnum,len(self.images)))
self.parent.app.processEvents()
status,points = cv2.findChessboardCorners( self.images[imnum], self.n_chessboard_points, flags=cv2.CALIB_CB_ADAPTIVE_THRESH )
self.chessboard_status.append(not status)
if status:
for j,point in enumerate(points):
self.chessboard_points_2D[imnum][j,:] = point[0]
self.status_text.setText('')
self.parent.app.restoreOverrideCursor()
if np.all(self.chessboard_status):
dialog = qt.QMessageBox(self)
dialog.setStandardButtons(qt.QMessageBox.Ok)
dialog.setTextFormat(qt.Qt.RichText)
dialog.setWindowTitle('Calcam - No Chessboards Detected')
dialog.setText("No {:d} x {:d} square chessboard patterns were found in the images.".format(self.chessboard_squares_x.value(),self.chessboard_squares_y.value()))
dialog.setInformativeText("Is the number of squares set correctly?")
dialog.setIcon(qt.QMessageBox.Warning)
dialog.exec_()
elif np.any(self.chessboard_status):
dialog = qt.QMessageBox(self)
dialog.setStandardButtons(qt.QMessageBox.Ok)
dialog.setTextFormat(qt.Qt.RichText)
dialog.setWindowTitle('Calcam - Chessboard Detection')
dialog.setText("A {:d} x {:d} square chessboard pattern could not be detected in the following {:d} of {:d} images, which will therefore not be included as additional chessboard constraints:".format(self.chessboard_squares_x.value(),self.chessboard_squares_y.value(),np.count_nonzero(self.chessboard_status),len(self.images)))
dialog.setInformativeText('<br>'.join(['[#{:d}] '.format(i+1) + self.filenames[i] for i in range(len(self.filenames)) if self.chessboard_status[i] ]))
dialog.setIcon(qt.QMessageBox.Warning)
dialog.exec_()
self.chessboard_status = [not status for status in self.chessboard_status]
self.detection_run = True
self.update_image_display()
if np.any(self.chessboard_status):
self.apply_button.setEnabled(True)
self.status_text.setText('<b>Chessboard patterns detected successfully in {:d} images. Click Apply to use these in Calcam.</b>'.format(np.count_nonzero(self.chessboard_status),len(self.images)))
else:
self.apply_button.setEnabled(False)
self.status_text.setText('')