python paperclip_python+opencv中最近出现的一些变化( OpenCV 官方的 Python tutorial目前好像还没有改过来?) 记一次全景图像的拼接...

最近在学习过程中发现opencv有了很多变动, OpenCV 官方的 Python tutorial目前好像还没有改过来,导致大家在学习上面都出现了一些问题,现在做一个小小的罗列,希望对大家有用

做的是关于全景图像的拼接,关于sift和surf的语法之后有需要会另开文章具体阐述,此篇主要是解决大家困惑许久的问题。

笔者python3.x

首先是安装上,必须先后安装pip install opencv_python和pip install opencv-contrib-python==3.3.0.10后面一个一定要指定版本号,因为版本上面最新的opencv-contrib-python-3.4.5.20版本好像申请了什么专利,所以我们可能无法调用的,安装上要是出现了报错,先别急着写在,重新运行一次语句,基本上就可能可以了。

然后是关于sift和surf这两条语句上面,它的语法函数也出现了变化,具体可以参考这个

好像是最近才修改的,真的走了很多弯路才走通。

#这里的代码有改动之后才能用

#sift = cv.xfeatures2d_SIFT().create()修改为

sift = cv2.xfeatures2d.SIFT_create()

hessian=400

#surf=cv2.SURF(hessian)修改为

surf=cv2.xfeatures2d.SURF_create(hessian)

下面给出两个代码,是借鉴了网友的,但是对于报错的部分和需要改正的点都已经纠错完毕了,希望对大家有所帮助。有其他的bug也欢迎留言。

示例1

6.jpg

7.jpg

效果图

#coding: utf-8

importnumpy as npimportcv2

leftgray= cv2.imread('6.jpg')

rightgray= cv2.imread('7.jpg')

hessian=400surf=cv2.xfeatures2d.SURF_create(hessian)#surf=cv2.SURF(hessian) #将Hessian Threshold设置为400,阈值越大能检测的特征就越少

kp1,des1=surf.detectAndCompute(leftgray,None) #查找关键点和描述符

kp2,des2=surf.detectAndCompute(rightgray,None)

FLANN_INDEX_KDTREE=0 #建立FLANN匹配器的参数

indexParams=dict(algorithm=FLANN_INDEX_KDTREE,trees=5) #配置索引,密度树的数量为5

searchParams=dict(checks=50) #指定递归次数#FlannBasedMatcher:是目前最快的特征匹配算法(最近邻搜索)

flann=cv2.FlannBasedMatcher(indexParams,searchParams) #建立匹配器

matches=flann.knnMatch(des1,des2,k=2) #得出匹配的关键点

good=[]#提取优秀的特征点

for m,n inmatches:if m.distance < 0.7*n.distance: #如果第一个邻近距离比第二个邻近距离的0.7倍小,则保留

good.append(m)

src_pts= np.array([ kp1[m.queryIdx].pt for m in good]) #查询图像的特征描述子索引

dst_pts = np.array([ kp2[m.trainIdx].pt for m in good]) #训练(模板)图像的特征描述子索引

H=cv2.findHomography(src_pts,dst_pts) #生成变换矩阵

h,w=leftgray.shape[:2]

h1,w1=rightgray.shape[:2]

shft=np.array([[1.0,0,w],[0,1.0,0],[0,0,1.0]])

M=np.dot(shft,H[0]) #获取左边图像到右边图像的投影映射关系

dst_corners=cv2.warpPerspective(leftgray,M,(w*2,h))#透视变换,新图像可容纳完整的两幅图

cv2.imshow('tiledImg1',dst_corners) #显示,第一幅图已在标准位置

dst_corners[0:h,w:w*2]=rightgray #将第二幅图放在右侧#cv2.imwrite('tiled.jpg',dst_corners)

cv2.imshow('tiledImg',dst_corners)

cv2.imshow('leftgray',leftgray)

cv2.imshow('rightgray',rightgray)

cv2.waitKey()

cv2.destroyAllWindows()

示例2

test1.jpg

test2.jpg

效果图

importnumpy as npimportcv2 as cvfrom matplotlib importpyplot as pltif __name__ == '__main__':

top, bot, left, right= 100, 100, 0, 500img1= cv.imread('test1.jpg')

img2= cv.imread('test2.jpg')

srcImg= cv.copyMakeBorder(img1, top, bot, left, right, cv.BORDER_CONSTANT, value=(0, 0, 0))

testImg= cv.copyMakeBorder(img2, top, bot, left, right, cv.BORDER_CONSTANT, value=(0, 0, 0))

img1gray=cv.cvtColor(srcImg, cv.COLOR_BGR2GRAY)

img2gray=cv.cvtColor(testImg, cv.COLOR_BGR2GRAY)#这里的代码有改动之后才能用

#sift = cv.xfeatures2d_SIFT().create()

sift =cv2.xfeatures2d.SIFT_create()#find the keypoints and descriptors with SIFT

kp1, des1 =sift.detectAndCompute(img1gray, None)

kp2, des2=sift.detectAndCompute(img2gray, None)#FLANN parameters

FLANN_INDEX_KDTREE = 1index_params= dict(algorithm=FLANN_INDEX_KDTREE, trees=5)

search_params= dict(checks=50)

flann=cv.FlannBasedMatcher(index_params, search_params)

matches= flann.knnMatch(des1, des2, k=2)#Need to draw only good matches, so create a mask

matchesMask = [[0, 0] for i inrange(len(matches))]

good=[]

pts1=[]

pts2=[]#ratio test as per Lowe's paper

for i, (m, n) inenumerate(matches):if m.distance < 0.7*n.distance:

good.append(m)

pts2.append(kp2[m.trainIdx].pt)

pts1.append(kp1[m.queryIdx].pt)

matchesMask[i]= [1, 0]

draw_params= dict(matchColor=(0, 255, 0),

singlePointColor=(255, 0, 0),

matchesMask=matchesMask,

flags=0)

img3= cv.drawMatchesKnn(img1gray, kp1, img2gray, kp2, matches, None, **draw_params)

plt.imshow(img3, ), plt.show()

rows, cols= srcImg.shape[:2]

MIN_MATCH_COUNT= 10

if len(good) >MIN_MATCH_COUNT:

src_pts= np.float32([kp1[m.queryIdx].pt for m in good]).reshape(-1, 1, 2)

dst_pts= np.float32([kp2[m.trainIdx].pt for m in good]).reshape(-1, 1, 2)

M, mask= cv.findHomography(src_pts, dst_pts, cv.RANSAC, 5.0)

warpImg= cv.warpPerspective(testImg, np.array(M), (testImg.shape[1], testImg.shape[0]), flags=cv.WARP_INVERSE_MAP)for col inrange(0, cols):if srcImg[:, col].any() andwarpImg[:, col].any():

left=colbreak

for col in range(cols-1, 0, -1):if srcImg[:, col].any() andwarpImg[:, col].any():

right=colbreakres= np.zeros([rows, cols, 3], np.uint8)for row inrange(0, rows):for col inrange(0, cols):if notsrcImg[row, col].any():

res[row, col]=warpImg[row, col]elif notwarpImg[row, col].any():

res[row, col]=srcImg[row, col]else:

srcImgLen= float(abs(col -left))

testImgLen= float(abs(col -right))

alpha= srcImgLen / (srcImgLen +testImgLen)

res[row, col]= np.clip(srcImg[row, col] * (1-alpha) + warpImg[row, col] * alpha, 0, 255)#opencv is bgr, matplotlib is rgb

res =cv.cvtColor(res, cv.COLOR_BGR2RGB)#show the result

plt.figure()

plt.imshow(res)

plt.show()else:print("Not enough matches are found - {}/{}".format(len(good), MIN_MATCH_COUNT))

matchesMask= None

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值