(相机校准)如何让我的循环读取图像只等待 10 秒,如果没有任何东西移动到下一张图像?

Posted

技术标签:

【中文标题】(相机校准)如何让我的循环读取图像只等待 10 秒,如果没有任何东西移动到下一张图像?【英文标题】:(Camera Calibration) How to make my loop to read images wait only for 10 seconds and if there is nothing move to the next image? 【发布时间】:2017-04-13 10:23:46 【问题描述】:

我正在编写代码以使用 openCVPython 中校准相机。我正在使用 30 张图像进行校准。这个想法是循环从一个图像开始,如果它没有检测到什么,等待一段时间并转到下一个图像。

我的目标是让循环仅等待每张图像 15 秒(例如),如果没有结果,则传递到下一张图像。

感谢您的帮助。

这里是代码。

    # -*- coding: utf-8 -*-
import numpy as np
import cv2
import glob
import math
import pickle
import matplotlib.pyplot as plt
import time

# Calcul de la distance
def _pdist(p1, p2):
    """
    Distance bwt two points. p1 = (x, y), p2 = (x, y)
    """

    return math.sqrt(math.pow(p1[0] - p2[0], 2) + math.pow(p1[1] - p2[1], 2))


print "Initializing"
# termination criteria
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)

# Définir le nombre de bords qu'on a dans le damier (dans notre cas 13*13)
n_rows = 13
n_cols = 13
n_cols_and_rows = (n_cols, n_rows)
n_rows_and_cols = (n_rows, n_cols)

# Prépar les points objet (0,0,0), (1,0,0), (2,0,0) ....,(6,5,0)
objp = np.zeros((n_rows * n_cols, 3), np.float32)
objp[:, :2] = np.mgrid[0:n_rows, 0:n_cols].T.reshape(-1, 2)

# Préparer deux tableaux pour sauvegarder les points objet et points images de totues les images trouvées.
objpoints = []  # 3d point in real world space
imgpoints = []  # 2d points in image plane.

# Les photos du damier qu'on a pris pour le test

mypath = "/home/stagiaire/Bureau/New_Calibrage/RGB/"

# mypath="/home/stagiaire/Bureau/DATA_new//Photos_damiers_test/GRE/"
# mypath="/home/stagiaire/Bureau/DATA_new/Photos_damiers_test/NIR/"
# mypath="/home/stagiaire/Bureau/DATA_new/Photos_damiers_test/RED/"
# mypath="/home/stagiaire/Bureau/DATA new/Photos_damiers_test/REG/"
# mypath="/home/stagiaire/Bureau/DATA_new/Photos_damiers_test/RGB/"


print "Getting images from " + mypath
images = glob.glob(mypath + '*.JPG')
print "images is: " + str(images)

criteria_calibrator = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
criteria = criteria_calibrator

for idx, fname in enumerate(images):
    print "\nImage " + fname
    if time.sleep(10):
        break
    img = cv2.imread(fname)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # Trouver les bords
    ret, corners = cv2.findChessboardCorners(gray, n_rows_and_cols, None)
    # Si trouvés, on ajoute les points obj et les points images
    if ret == True:
        print " found " + str(len(corners)) + " corners."
    objpoints.append(objp)
    # cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria) didnt work, I couldnt make it work copying the calibrator code
    imgpoints.append(corners)

    # Dessiner et afficher les bords sur la photo originale
    cv2.drawChessboardCorners(img, n_rows_and_cols, corners, ret)
    cv2.imshow('img', img)
    cv2.waitKey(500)

# Afficher combien de points image et points objet on a trouvé
print "objpoints len: " + str(len(objpoints))
print "imgpoints len: " + str(len(imgpoints))

# Trouver la matrice de la caméra et l'enregistrer dans le dossier du data (photos du test)

try:
    ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)
    datathings = (ret, mtx, dist, rvecs, tvecs)
    outf = open(mypath + "calibration_return_values_rows_and_cols.pickle", "rb")
    pickle.dump(datathings, outf)
    fieldnames = ["ret", "mtx", "dist", "rvecs", "tvecs"]
    for fieldname, data in zip(fieldnames, datathings):
        print fieldname + ": "
        print data
    print "ret, mtx, dist, rvecs, tvecs:"
    print (ret, mtx, dist, rvecs, tvecs)
except:
    print "Failed getting cv2.calibrateCamera"
    pass
# cv2.destroyAllWindows()


# Calibration
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)

img = cv2.imread('/home/stagiaire/Bureau/New_Calibrage/GRE/IMG_700101_000255_0000_RGB.JPG')

h, w = img.shape[:2]
newcameramtx, roi = cv2.getOptimalNewCameraMatrix(mtx, dist, (w, h), 1, (w, h))

# undistortion
dst = cv2.undistort(img, mtx, dist, None, newcameramtx)

# crop l'image
x, y, w, h = roi
dst = dst[y:y + h, x:x + w]
cv2.imwrite('Desktop/imagecalibre.png', dst)

# Affichage l'image originale au coté de l'image calibrée
plt.subplot(221), plt.imshow(img), plt.title('image originale')
plt.subplot(222), plt.imshow(dst), plt.title('image calibree')
plt.show()

# Calcul de l'erreur
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)
    tot_error = error

print "total error: ", mean_error / len(objpoints)

这是我想要更改循环的部分,我尝试过类似 time.sleep() 的方法,但它不起作用。

for idx, fname in enumerate(images):
    print "\nImage " + fname
    if time.sleep(10):
        break
    img = cv2.imread(fname)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # Trouver les bords
    ret, corners = cv2.findChessboardCorners(gray, n_rows_and_cols, None)
    # Si trouvés, on ajoute les points obj et les points images
    if ret == True:
        print " found " + str(len(corners)) + " corners."
    objpoints.append(objp)
    # cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria) didnt work, I couldnt make it work copying the calibrator code
    imgpoints.append(corners)

【问题讨论】:

【参考方案1】:

尝试删除

if time.sleep(10):
    break

改变

cv2.waitKey(500)

cv2.waitKey(10000) # waits 10 seconds (10000 ms) for a pressed key

这是cv2.waitKey的链接

--- 编辑---

也许你可以这样尝试:

for idx, fname in enumerate(images):
    print "\nImage " + fname
    img = cv2.imread(fname)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # Trouver les bords
    ret, corners = cv2.findChessboardCorners(gray, n_rows_and_cols, None)
    # Si trouvés, on ajoute les points obj et les points images
    if ret == True:
        print " found " + str(len(corners)) + " corners."

        objpoints.append(objp)
        # cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria) didnt work, I couldnt make it work copying the calibrator code
        imgpoints.append(corners)

        # Dessiner et afficher les bords sur la photo originale
        cv2.drawChessboardCorners(img, n_rows_and_cols, corners, ret)
        cv2.imshow('img', img)
        cv2.waitKey(0)

    else:
        print " no corners found"

【讨论】:

谢谢楼主,我刚试了下,没有任何效果!代码仍在运行,并在第一张图片中阻塞。 1. cv2.waitKey图像窗口 而不是在 终端 中等待按下的键。 2.如果不按键,图片会每10秒自动移到下一张吗?还是第一张图片会永远挡在那里? 图片在后面处理它没有显示,如果代码检测到什么就会显示,在我的例子中,我说的是它没有检测到任何东西的情况。处理在后台,如果它在 15 秒内没有检测到任何东西,我需要它直接转到下一张图片...

以上是关于(相机校准)如何让我的循环读取图像只等待 10 秒,如果没有任何东西移动到下一张图像?的主要内容,如果未能解决你的问题,请参考以下文章

使用数码相机进行相机校准

棋盘大小如何影响准确的相机校准?

使用单个校准相机从 2D 图像中获取世界坐标

强大的相机校准

不使用 cv2.findChessboardCorners 在 Python 中校准 OpenCV 相机

使用来自 OpenCV 的转换矩阵手动进行图像校准