Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/351.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么openCV warpAffine将我的整个图像设置为零?_Python_Opencv_Image Processing - Fatal编程技术网

Python 为什么openCV warpAffine将我的整个图像设置为零?

Python 为什么openCV warpAffine将我的整个图像设置为零?,python,opencv,image-processing,Python,Opencv,Image Processing,因此,我试图在OpenCV Python中编写一个函数,它将获取一个图像,一个显示已识别手指区域的二进制图像,以及一个2x(图像宽度)矩阵,该矩阵包含在该图像中找到的手指边缘的位置数据,作为输入,然后对图像进行归一化并将其作为输出返回 为了使其正常化,我将通过平行于边缘的手指区域投影一条基线,然后尝试旋转图像,使该基线平行于图像矩形的边缘。因此,该函数绘制基线,确定仿射变换矩阵,然后使用WarpeAffine对图像进行归一化。不幸的是,由于我不太清楚的原因,warpAffine的输出只是一个满是

因此,我试图在OpenCV Python中编写一个函数,它将获取一个图像,一个显示已识别手指区域的二进制图像,以及一个2x(图像宽度)矩阵,该矩阵包含在该图像中找到的手指边缘的位置数据,作为输入,然后对图像进行归一化并将其作为输出返回

为了使其正常化,我将通过平行于边缘的手指区域投影一条基线,然后尝试旋转图像,使该基线平行于图像矩形的边缘。因此,该函数绘制基线,确定仿射变换矩阵,然后使用WarpeAffine对图像进行归一化。不幸的是,由于我不太清楚的原因,warpAffine的输出只是一个满是零的矩阵。我的代码如下所示。任何帮助都将不胜感激,谢谢!:)


正如Mika所评论的,rotmat前两行的最后一列应该是翻译

矩阵的平移系数为0,0:

rotmat = np.float32([[math.cos(rot), math.sin(rot), 0], [-math.sin(rot), math.cos(rot), 0]])
这种旋转矩阵是“中心变换”矩阵——当(0,0)坐标位于中心坐标时,变换用于变换(x,y)坐标

变换图像坐标时,(0,0)为左上角坐标,因此变换不应为(0,0)


还有其他问题(很难理解)

以下代码的目的是什么:

tmat = np.float32([[1, 0, 0], [0, 1, tr]])
tfmat = rotmat * tmat
它看起来像转换链,但NumPy中的
*
是元素乘法,转换链需要矩阵乘法

tfmat = rotmat @ tmat
这是行不通的,因为转换链需要平方矩阵(3x3)。
仿射变换矩阵的最后一行是
[0,0,1]


要获取旋转的变换矩阵,可以使用OpenCV方法。
结果应用“左上”变换(平移系数不是零)。
该方法返回2x3矩阵-您需要添加
[0,0,1]
作为最后一行,以便将其转换为转换矩阵


将“居中”转换为“左上”转换:

如果您使用的是中心变换,并且需要将其转换为“左上”变换,那么数学就不那么难了。
矩阵表示法是:
trans=cen2top@centered\u trans@top2cen
(当
@
应用矩阵乘法时)


以下是构建“左上”旋转变换矩阵的示例(请阅读注释):


结果:


我试着教你一些数学…
我希望它能帮助您解决问题标题处的问题:

为什么openCV warpAffine将我的整个图像设置为零

使用错误的变换矩阵扭曲可能会导致图像充满零



可能还有其他问题,但我无法测试您的代码,因为您没有发布
img
fvr
,以及
边缘

您使用了哪个角度?如果围绕原点(图像的左上角)旋转,很容易将整个图像旋转到视图之外,例如>=90度计数器顺时针旋转t在我看来很奇怪。第三行的最后一个元素应为1。前两行的最后一列应该是译文?谢谢你提供了非常详细的答案:)
tfmat = rotmat @ tmat
import numpy as np
import cv2

img = cv2.imread('chelsea.png')

rot = 30*np.pi/180

cols, rows = img.shape[1], img.shape[0]

# Centered transformation - translation coefficients are 0
centered_trans = np.float64([[ np.cos(rot), np.sin(rot), 0], 
                             [-np.sin(rot), np.cos(rot), 0],
                             [ 0,           0,           1]])

# Transform top-left coordinate to centered coordinate: x translation = -(cols-1)/2, y translation = -(rows-1)/2
top2cen = np.float64([[1,    0,   -(cols-1)/2],
                      [0,    1,   -(rows-1)/2],
                      [0,    0,    1]])

# Transform centered coordinate to top-left coordinate - x translation = (cols-1)/2, y translation = (rows-1)/2
cen2top = np.float64([[1,      0,    (cols-1)/2],
                      [0,      1,    (rows-1)/2],
                      [0,      0,    1]])

# We need the rotation matrix to be "top left" - coordinate (0, 0) is the top left coordinate:
# Assume column vector u = [x, y, 1] applies top-left coordinates.
# 1. Transform u to centered coordinates:              centerd_u = top2cen*u
# 2. Apply centered_trans on centerd_u:                centerd_v = centered_trans*centerd_u = centered_trans*top2cen*u
# 3. Transform centerd_v to top-left coordinates:      v = cen2top*centerd_v = cen2top*centered_trans*top2cen*u
# The transformation from "top-left" to "top-left" is:                         cen2top*centered_trans*top2cen
trans = cen2top @ centered_trans @ top2cen  # Note: we don't really need to use matrix multiplications for solving this.

# Remove the last row.
rotmat = trans[0:2, :]

# The result should be the same result as cv2.getRotationMatrix2D
# https://docs.opencv.org/master/da/d6e/tutorial_py_geometric_transformations.html
# cols-1 and rows-1 are the coordinate limits.
M = cv2.getRotationMatrix2D(((cols-1)/2.0, (rows-1)/2.0), 30, 1)  # Used as reference


img = cv2.warpAffine(img, rotmat, (cols, rows), cv2.INTER_CUBIC)

cv2.imshow('img', img)
cv2.waitKey()
cv2.destroyAllWindows()