GVKun编程网logo

Python Opencv SolvePnP产生错误的翻译向量(python opencv报错)

18

对于想了解PythonOpencvSolvePnP产生错误的翻译向量的读者,本文将提供新的信息,我们将详细介绍pythonopencv报错,并且为您提供关于36篇博文带你学完opencv:python

对于想了解Python Opencv SolvePnP产生错误的翻译向量的读者,本文将提供新的信息,我们将详细介绍python opencv报错,并且为您提供关于36 篇博文带你学完 opencv :python+opencv 进阶版学习笔记目录、OpenCV Python cv2.perspectiveTransform、opencv+python 机读卡识别之试错(二)尝试自建 opencv 分类器、OpenCV-Python OpenCV中的K-Means聚类 | 五十八的有价值信息。

本文目录一览:

Python Opencv SolvePnP产生错误的翻译向量(python opencv报错)

Python Opencv SolvePnP产生错误的翻译向量(python opencv报错)

我正在尝试使用单应性在Blender 3d中校准并找到单个虚拟相机的位置和旋转。我正在使用Blender,以便在进入更加困难的现实世界之前可以仔细检查结果。

从固定相机的角度来看,我在不同位置和旋转位置上绘制了十张国际象棋棋盘的图片。使用OpenCV的Python,我曾经cv2.calibrateCamera从十张图像中从棋盘的检测到的角落中找到本征矩阵,然后将其cv2.solvePnP用于寻找外部参数(平移和旋转)。

但是,尽管估计的参数与实际参数很接近,但是仍然有些麻烦。我对翻译的初步估计是(-0.11205481,-0.0490256,8.13892491)。实际位置是(0,8.07105)。很接近吧?

但是,当我稍微移动和旋转相机并重新渲染图像时,估计的平移距离就更远了。估计:(-0.15933154,0.13367286,9.34058867)。实际:(-1.7918,-1.51073,9.76597)。Z值接近,而X和Y则不。

我完全感到困惑。如果有人可以帮助我解决这个问题,我将不胜感激。这是代码(基于OpenCV随附的Python2校准示例):

#imports left out
USAGE = '''
USAGE: calib.py [--save <filename>] [--debug <output path>] [--square_size] [<image mask>]
'''

args,img_mask = getopt.getopt(sys.argv[1:],'',['save=','debug=','square_size='])
args = dict(args)
try: img_mask = img_mask[0]
except: img_mask = '../cpp/0*.png'
img_names = glob(img_mask)
debug_dir = args.get('--debug')
square_size = float(args.get('--square_size',1.0))

pattern_size = (5,8)
pattern_points = np.zeros( (np.prod(pattern_size),3),np.float32 )
pattern_points[:,:2] = np.indices(pattern_size).T.reshape(-1,2)
pattern_points *= square_size

obj_points = []
img_points = []
h,w = 0,0
count = 0
for fn in img_names:
    print 'processing %s...' % fn,img = cv2.imread(fn,0)
    h,w = img.shape[:2]
    found,corners = cv2.findChessboardCorners(img,pattern_size)

    if found:
        if count == 0:
            #corners first is a list of the image points for just the first image.
            #This is the image I know the object points for and use in solvePnP
            corners_first =  []
            for val in corners:
                corners_first.append(val[0])                
            np_corners_first = np.asarray(corners_first,np.float64)                
        count+=1
        term = ( cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_COUNT,30,0.1 )
        cv2.cornerSubPix(img,corners,(5,5),(-1,-1),term)
    if debug_dir:
        vis = cv2.cvtColor(img,cv2.COLOR_GRAY2BGR)
        cv2.drawChessboardCorners(vis,pattern_size,found)
        path,name,ext = splitfn(fn)
        cv2.imwrite('%s/%s_chess.bmp' % (debug_dir,name),vis)
    if not found:
        print 'chessboard not found'
        continue
    img_points.append(corners.reshape(-1,2))
    obj_points.append(pattern_points)

    print 'ok'

rms,camera_matrix,dist_coefs,rvecs,tvecs = cv2.calibrateCamera(obj_points,img_points,(w,h))
print "RMS:",rms
print "camera matrix:\n",camera_matrix
print "distortion coefficients: ",dist_coefs.ravel()    
cv2.destroyAllWindows()

np_xyz = np.array(xyz,np.float64).T #xyz list is from file. Not shown here for brevity
camera_matrix2 = np.asarray(camera_matrix,np.float64)
np_dist_coefs = np.asarray(dist_coefs[:,:],np.float64)

found,rvecs_new,tvecs_new = cv2.solvePnP(np_xyz,np_corners_first,camera_matrix2,np_dist_coefs)

np_rodrigues = np.asarray(rvecs_new[:,np.float64)
print np_rodrigues.shape
rot_matrix = cv2.Rodrigues(np_rodrigues)[0]

def rot_matrix_to_euler(R):
    y_rot = asin(R[2][0]) 
    x_rot = acos(R[2][2]/cos(y_rot))    
    z_rot = acos(R[0][0]/cos(y_rot))
    y_rot_angle = y_rot *(180/pi)
    x_rot_angle = x_rot *(180/pi)
    z_rot_angle = z_rot *(180/pi)        
    return x_rot_angle,y_rot_angle,z_rot_angle

print "Euler_rotation = ",rot_matrix_to_euler(rot_matrix)
print "Translation_Matrix = ",tvecs_new

36 篇博文带你学完 opencv :python+opencv 进阶版学习笔记目录

36 篇博文带你学完 opencv :python+opencv 进阶版学习笔记目录

基础版学习笔记传送门
36 篇博文带你学完 opencv :python3+opencv 学习笔记汇总目录(基础版)

进阶版笔记

项目
opencv 进阶学习笔记 1: 调用摄像头用法大全(打开摄像头,打开摄像头并实时不断截屏,读取视频并截图)
opencv 进阶学习笔记 2:numpy 操作图像,色彩空间,查找指定颜色范围,通道分离与合并
opencv 进阶学习笔记 3:像素运算和图像亮度对比度调节
opencv 进阶学习笔记 4:ROI 和泛洪扩充
opencv 进阶学习笔记 5:图像模糊操作,图像锐化,边缘保留滤波 EPF(图像滤镜)
opencv 进阶学习笔记 6:使用鼠标在图像上绘制矩形框或者多边形框
opencv 进阶学习笔记 7:直方图,直方图均衡化,直方图比较,直方图反向投影
opencv 进阶学习笔记 8:模板匹配
opencv 进阶学习 9:图像阈值大全,图像二值化,超大图像二值化
opencv 进阶学习笔记 10:图像金字塔和图像梯度
opencv 进阶学习笔记 11:cannny 边缘检测,直线检测,圆检测
opencv 进阶学习笔记 12:轮廓发现和对象测量
opencv 进阶学习笔记 13:图像形态学操作大全(膨胀,腐蚀,开闭,黑帽,顶帽,梯度)python 版
opencv 进阶学习笔记 14:分水岭算法 实现图像分割

OpenCV 告一段落,接下来,该实战啦。
计算机视觉三大任务,分类,监测,分割。
意见其他一些任务…
图像生成,OCR…


电气专业的计算机萌新,写博文不容易,如果你觉得本文对你有用,请点个赞支持下,谢谢。

OpenCV Python cv2.perspectiveTransform

OpenCV Python cv2.perspectiveTransform

我目前正在尝试使用OpenCV和Python进行视频稳定化。我使用以下函数来计算旋转:

def accumulate_rotation(src, theta_x, theta_y, theta_z, timestamps, prev, current, f, gyro_delay=None, gyro_drift=None, shutter_duration=None):    if prev == current:        return src    pts = []    pts_transformed = []    for x in range(10):        current_row = []        current_row_transformed = []        pixel_x = x * (src.shape[1] / 10)        for y in range(10):            pixel_y = y * (src.shape[0] / 10)            current_row.append([pixel_x, pixel_y])            if shutter_duration:                y_timestamp = current + shutter_duration * (pixel_y - src.shape[0] / 2)            else:                y_timestamp = current            transform = getAccumulatedRotation(src.shape[1], src.shape[0], theta_x, theta_y, theta_z, timestamps, prev,                                               current, f, gyro_delay, gyro_drift)            output = cv2.perspectiveTransform(np.array([[pixel_x, pixel_y]], dtype="float32"), transform)            current_row_transformed.append(output)        pts.append(current_row)        pts_transformed.append(current_row_transformed)    o = utilities.meshwarp(src, pts_transformed)    return o

我遇到以下错误output = cv2.perspectiveTransform(np.array([[pixel_x, pixel_y]],dtype="float32"), transform)

cv2.error: /Users/travis/build/skvark/opencv-python/opencv/modules/core/src/matmul.cpp:2271: error: (-215) scn + 1 ==m.cols in function perspectiveTransform

任何帮助或建议,将不胜感激。

答案1

小编典典

确实需要在将来的版本中更改此实现。

从OpenCV文档中获得perspectiveTransform()

src –输入 两通道 (…)浮点数组

我偏重强调。

>>> A = np.array([[0, 0]], dtype=np.float32)>>> A.shape(1, 2)

因此,从这里我们看到的A只是一个单通道矩阵,即二维矩阵。一排,两列。相反,您需要一个 两通道
图像,即一个三维矩阵,其中三维尺寸的长度为2或3,具体取决于您是以2D还是3D点进行发送。

简而言之,您需要再添加一组括号,以三维方式发送要发送的点集,其中x值在第一个通道中,而y值在第二个通道中。

>>> A = np.array([[[0, 0]]], dtype=np.float32)>>> A.shape(1, 1, 2)

它不是直观的,尽管有文档记录,但在这一点上不是很明确。

opencv+python 机读卡识别之试错(二)尝试自建 opencv 分类器

opencv+python 机读卡识别之试错(二)尝试自建 opencv 分类器

这里是效果不好的系列,但可能还是有丁点启示作用。效果好的系列:https://my.oschina.net/u/3268732/blog/1236298

opencv 自建 haartrain 分类器,这是一个基于 haar 特征的一个玩意儿,人脸识别用的挺多的,但他们都可以直接引用一个 xml 文件,好气哦,做数字识别只有想办法自己建了。

首先先要从 opencv 的包目录下找到 bin 文件夹,在把里面的 createsamples.exe 和 haartrain.exe 文件拷出来,createsamples 文件针对正类数据进行特征描述,而 haartrain 是结合 createsamples 的输出文件建立模型。 所以建了两个文件夹分别针对 createsamples 和 haartrain

文件夹的样子

createsample 里面先放一个刚刚的 createsamples.exe 自建一个 sample 文件夹用来存放正确的样本,再写个 pos.txt 来描述 sample,新建一个 vec.txt,啥都不写,新建个 txt 改类型为 bat 格式,这个用来写命令行总的来说,文件夹是这样的:

createsamples

pos.txt 内容一览:

pos

说明:第一列文件目录及文件名,第二列为目标文件中有多少个正样本的图,第三列与第四列分别为起始 x 坐标与 y 坐标,第五列为截取宽度。若是多个目标,再在后面添加坐标,宽高。

create.bat 内容一览:

create

说明:-info + 描述文件,-vec + 输出文件 -w + 训练样本宽,-h + 高,-num + 训练样本数目,算清楚就好了,不是图片数目,而是 pos.txt 里第二列数值总和。

之后运行 create.bat 文件,发现 vec 被填充。如果报错是缺失一系列 dll 文件,那么把 opencv.bin 下的文件全部扔到 createsample 的文件夹下面就好了

将 vec.txt 文件考入 train 文件夹,新建一个 data 文件夹,再像刚才那样建个 sample 文件夹啊,一个描述文件 sample.txt, 一个 haartrain.bat 文件夹。 sample.txt 文件如下:

sample

只用给出文件路径就好了

haartrain.bat 文件描述:

haartrain 说明:-vec+vec 文件,-bg + 描述文件,-npos + 正例样本数,和上面计算方法一样,-nneg + 负样本数,只用数图个数,-nstages + 一个参数,-w + 宽,-h + 高,-data + 新建的文件夹 data

弄完就玩了,讲道理会在 data 目录下生成一堆东西,然而因为样本数太少了,居然什么都没有…… 绝望…… 放弃。

另附:自动图片切割代码:

for i in range(1,21):
    image=cv2.imread("ipadair (%d).jpg"%i)
    #中间下可以添加预处理的部分,以得到最好效果
    #image[起始y:终止y,起始x:终止x]
    train = image[liney10:liney11, linex10:linex11]
    cv2.imwrite(''1''+''%d''%i+''.jpg'',train)

OpenCV-Python OpenCV中的K-Means聚类 | 五十八

OpenCV-Python OpenCV中的K-Means聚类 | 五十八

目标

  • 了解如何在OpenCV中使用cv.kmeans()函数进行数据聚类

理解参数

输入参数

  1. sample:它应该是np.float32数据类型,并且每个功能都应该放在单个列中。
  2. nclusters(K):结束条件所需的簇数
  3. criteria:这是迭代终止条件。满足此条件后,算法迭代将停止。实际上,它应该是3个参数的元组。它们是(type,max_iter,epsilon)
    a. 终止条件的类型。它具有3个标志,如下所示:

    • cv.TERM_CRITERIA_EPS-如果达到指定的精度epsilon,则停止算法迭代。
    • cv.TERM_CRITERIA_MAX_ITER-在指定的迭代次数max_iter之后停止算法。
    • cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER-当满足上述任何条件时,停止迭代。
b. max_iter-一个整数,指定最大迭代次数。
c. epsilon-要求的精度
  1. attempts:该标志用于指定使用不同的初始标签执行算法的次数。该算法返回产生最佳紧密度的标签。该紧凑性作为输出返回。
  2. flags:此标志用于指定初始中心的获取方式。通常,为此使用两个标志:cv.KMEANS_PP_CENTERScv.KMEANS_RANDOM_CENTERS

输出参数

  1. 紧凑度:它是每个点到其相应中心的平方距离的总和。
  2. 标签:这是标签数组(与上一篇文章中的“代码”相同),其中每个元素标记为“0”,“ 1” .....
  3. 中心:这是群集中心的阵列。

现在,我们将通过三个示例了解如何应用K-Means算法。

1. 单特征数据

考虑一下,你有一组仅具有一个特征(即一维)的数据。例如,我们可以解决我们的T恤问题,你只用身高来决定T恤的尺寸。因此,我们首先创建数据并将其绘制在Matplotlib中

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
x = np.random.randint(25,100,25)
y = np.random.randint(175,255,25)
z = np.hstack((x,y))
z = z.reshape((50,1))
z = np.float32(z)
plt.hist(z,256,[0,256]),plt.show()

因此,我们有了“ z”,它是一个大小为50的数组,值的范围是0到255。我将“z”重塑为列向量。
如果存在多个功能,它将更加有用。然后我制作了np.float32类型的数据。
我们得到以下图像:

现在我们应用KMeans函数。在此之前,我们需要指定标准。我的标准是,每当运行10次算法迭代或达到epsilon = 1.0的精度时,就停止算法并返回答案。

# 定义终止标准 = ( type, max_iter = 10 , epsilon = 1.0 )
criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 10, 1.0)
# 设置标志
flags = cv.KMEANS_RANDOM_CENTERS
# 应用K均值
compactness,labels,centers = cv.kmeans(z,2,None,criteria,10,flags)

这为我们提供了紧凑性,标签和中心。在这种情况下,我得到的中心分别为60和207。标签的大小将与测试数据的大小相同,其中每个数据的质心都将标记为“ 0”,“ 1”,“ 2”等。现在,我们根据标签将数据分为不同的群集。

A = z[labels==0]
B = z[labels==1]

现在我们以红色绘制A,以蓝色绘制B,以黄色绘制其质心。

# 现在绘制用红色''A'',用蓝色绘制''B'',用黄色绘制中心
plt.hist(A,256,[0,256],color = ''r'')
plt.hist(B,256,[0,256],color = ''b'')
plt.hist(centers,32,[0,256],color = ''y'')
plt.show()

得到了以下结果:

2. 多特征数据

在前面的示例中,我们仅考虑了T恤问题的身高。在这里,我们将同时考虑身高和体重,即两个特征。
请记住,在以前的情况下,我们将数据制作为单个列向量。每个特征排列在一列中,而每一行对应于一个输入测试样本。
例如,在这种情况下,我们设置了一个大小为50x2的测试数据,即50人的身高和体重。第一列对应于全部50个人的身高,第二列对应于他们的体重。第一行包含两个元素,其中第一个是第一人称的身高,​​第二个是他的体重。类似地,剩余的行对应于其他人的身高和体重。查看下面的图片:

现在,我直接转到代码:

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
X = np.random.randint(25,50,(25,2))
Y = np.random.randint(60,85,(25,2))
Z = np.vstack((X,Y))
# 将数据转换未 np.float32
Z = np.float32(Z)
# 定义停止标准,应用K均值
criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 10, 1.0)
ret,label,center=cv.kmeans(Z,2,None,criteria,10,cv.KMEANS_RANDOM_CENTERS)
# 现在分离数据, Note the flatten()
A = Z[label.ravel()==0]
B = Z[label.ravel()==1]
# 绘制数据
plt.scatter(A[:,0],A[:,1])
plt.scatter(B[:,0],B[:,1],c = ''r'')
plt.scatter(center[:,0],center[:,1],s = 80,c = ''y'', marker = ''s'')
plt.xlabel(''Height''),plt.ylabel(''Weight'')
plt.show()

我们得到如下结果:

3.颜色量化

颜色量化是减少图像中颜色数量的过程。这样做的原因之一是减少内存。有时,某些设备可能会受到限制,因此只能产生有限数量的颜色。同样在那些情况下,执行颜色量化。在这里,我们使用k均值聚类进行颜色量化。

这里没有新内容要解释。有3个特征,例如R,G,B。因此,我们需要将图像重塑为Mx3大小的数组(M是图像中的像素数)。在聚类之后,我们将质心值(也是R,G,B)应用于所有像素,以使生成的图像具有指定数量的颜色。再一次,我们需要将其重塑为原始图像的形状。下面是代码:

import numpy as np
import cv2 as cv
img = cv.imread(''home.jpg'')
Z = img.reshape((-1,3))
# 将数据转化为np.float32
Z = np.float32(Z)
# 定义终止标准 聚类数并应用k均值
criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 10, 1.0)
K = 8
ret,label,center=cv.kmeans(Z,K,None,criteria,10,cv.KMEANS_RANDOM_CENTERS)
# 现在将数据转化为uint8, 并绘制原图像
center = np.uint8(center)
res = center[label.flatten()]
res2 = res.reshape((img.shape))
cv.imshow(''res2'',res2)
cv.waitKey(0)
cv.destroyAllWindows()

我们可以看的K=8的结果

欢迎关注磐创AI博客站:
http://panchuang.net/

OpenCV中文官方文档:
http://woshicver.com/

欢迎关注磐创博客资源汇总站:
http://docs.panchuang.net/

关于Python Opencv SolvePnP产生错误的翻译向量python opencv报错的问题我们已经讲解完毕,感谢您的阅读,如果还想了解更多关于36 篇博文带你学完 opencv :python+opencv 进阶版学习笔记目录、OpenCV Python cv2.perspectiveTransform、opencv+python 机读卡识别之试错(二)尝试自建 opencv 分类器、OpenCV-Python OpenCV中的K-Means聚类 | 五十八等相关内容,可以在本站寻找。

本文标签: