最终结果显示图像失真。有人可以告诉我发生了什么事吗?我对OpenCV没有太多经验。
我有一个3D图像,并使用PCA将其尺寸减小为2D。之后,我想计算单应矩阵,并将2D图像调整(warpingPerspective)为3D版本(3D但以2D观看)。
import numpy as np
import scipy.io as spio
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import cv2
from skimage import measure
from sklearn.manifold import TSNE
from sklearn.decomposition import PCA
MAX_FEATURES = 10000
NOISE = 0.05
# read, plot and store image of dataset.
filename='chainlink'
data_file = filename+'.mat'
data_matlab = spio.loadmat(data_file)
data_matrix = data_matlab['Xtrain']
data_fig = plt.figure()
ax = plt.axes()
ax = plt.axes(projection='3d')
ax.axis('off')
ax.scatter(data_matrix[:,0], data_matrix[:,1], data_matrix[:,2], c=data_matrix[:,2])
data_fig.tight_layout()
data_fig.savefig(filename+'3D.png', dpi=300)
# reduce the dataset to 2D with PCA.
pca = PCA(n_components=2)
data_pca = pca.fit_transform(data_matrix)
pca_fig = plt.figure()
ax = plt.axes()
ax.axis('off')
ax.scatter(data_pca[:,0], data_pca[:,1], c=data_pca[:,1],facecolor=(1.0, 0.47, 0.42))
pca_fig.tight_layout()
pca_fig.savefig(filename+'2D_PCA.png',dpi=300)
# just load images stored before.
img_3D = cv2.imread(filename+"3D.png")
img_pca = cv2.imread(filename+"2D_PCA.png")
# Convert to images grayscale, plot and store them.
img_gray_3D = cv2.cvtColor(img_3D, cv2.COLOR_BGR2GRAY)
img_gray_pca = cv2.cvtColor(img_pca, cv2.COLOR_BGR2GRAY)
height_gray_3D, width_gray_3D = img_gray_3D.shape
height_gray_pca, width_gray_pca = img_gray_pca.shape
plt.matshow(img_gray_3D, cmap='Greys_r')
plt.matshow(img_gray_pca, cmap='Greys_r')
plt.imsave(filename+'_img_gray_3D.png', img_gray_3D, dpi=300)
plt.imsave(filename+'_img_gray_pca.png', img_gray_pca, dpi=300)
#ORB (Oriented FAST and Rotated BRIEF).
orb_detector = cv2.ORB_create(MAX_FEATURES)
# The first arg is the image, second arg is the mask.
kp3D, d3D = orb_detector.detectAndCompute(img_gray_3D, None)
kpPCA, dPCA = orb_detector.detectAndCompute(img_gray_pca, None)
# Match features between the two images. Create a Brute Force matcher with
# Hamming distance as measurement mode. BFMatcher, a brute force matcher.
matcher = cv2.DescriptorMatcher_create(cv2.DESCRIPTOR_MATCHER_BRUTEFORCE_HAMMING)
matcher = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck = True)
# Match the two sets of descriptors.
matches_d3D_dPCA = matcher.match(d3D, dPCA, None)
# Draw matches. image 3D and image 2D withPCA.
draw_matches_3D_PCA = cv2.drawMatches(img_gray_3D, kp3D, img_gray_pca, kpPCA, matches_d3D_dPCA, None,flags=2)
plt.imshow(draw_matches_3D_PCA)
plt.show()
plt.imsave(filename+'_matches_3D_PCA.png', draw_matches_3D_PCA, dpi=300)
#total of matches.
total_matches_d3D_dPCA = len(matches_d3D_dPCA)
total_matches_d3D_dTSNE = len(matches_d3D_dTSNE)
# take descriptors from matches.
p3D = np.zeros((total_matches_d3D_dPCA, 2), dtype=np.float32)
pPCA = np.zeros((total_matches_d3D_dPCA, 2), dtype=np.float32)
for i in range(len(matches_d3D_dPCA)):
p3D[i, :] = kp3D[matches_d3D_dPCA[i].queryIdx].pt
pPCA[i, :] = kpPCA[matches_d3D_dPCA[i].trainIdx].pt
# Find the homography matrices. 
homography_3D_PCA, mask_3D_PCA = cv2.findHomography(pPCA, p3D, cv2.RANSAC)
# Use Homography matrix to transform the original data image with relation to the reference image.
transformed_img_3D_PCA = cv2.warpPerspective(img_gray_pca, homography_3D_PCA, (width_gray_3D, height_gray_3D))
# store result (here is the problem: result image is not what I spected)
cv2.imwrite('transformed_img_3D_PCA.jpg', transformed_img_3D_PCA)
我希望匹配的结果将是2D和图像尽可能接近3D图像。resulted image
数据集的链接可在此处下载:https://drive.google.com/open?id=1IrPUrt_jRAFjNVY3LraDZxjU1k4qHCpi