图片拼接软件app,图片拼接长图怎么拼
图片拼接-全景图合成开发环境python 3 opencv-contrib-python-34 .2 .16 opencv-python-3。4 .2 .16 pyqt 5-5。15 .6基本思路撒特征提取弗兰恩特征匹配单应性矩阵仿射变换图片融合最大内接矩形裁剪图像使用者界面界面显示代码程序完整工程:gitee . com/wangchaosun……
图片融合merge_pic.py
将数组作为铭牌导入
导入cv2
LEFTDIR=1
RIGHTDIR=2
#获取筛选,弗兰机器
极好的获取机器():
FLANN_INDEX_KDTREE=1
INDEX _ params=dict(算法=FLANN _ INDEX _ KD树,树=5)
search_params=dict(checks=50)
flann=cv2 .flanbasedmatcher(index _ params,search_params)
sift=cv2.xfeatures2d_SIFT().创建()
回筛,弗兰恩
def imgProcess(img,top,bot,left,right):
imgBord=cv2.copyMakeBorder(img,top,bot,left,right,cv2 .BORDER_CONSTANT,value=(0,0,0))
imgGray=cv2.cvtColor(imgBord,cv2 .COLOR_BGR2GRAY)
返回伊姆博德,伊姆格雷
def findEdgeDot(img,x1,x2,y1,y2):
dotsum=0
对于范围内的我(x1,x2 ^ 1):
对于范围内的j(y1,y2 1):
如果不是img.item(j,I):
dotsum=1
返回点总和
def getsmallouterect(img):
gray=cv2.cvtColor(img,cv2 .COLOR_BGR2GRAY)
thresh,binary=cv2.threshold(gray,1255,cv2 .THRESH_BINARY)
图像,轮廓,层次=cv2.findContours(二进制,cv2 .RETR _外部,cv2 .CHAIN_APPROX_SIMPLE)
areaList=[]
对于轮廓中的轮廓:
area=cv2.contourArea(contour)
areaList.append(area)
返回cv2。边界矩形(轮廓[NP。arg max(区域列表)])
def getMaxInnerRect(img,step): #输入的图像是二进制的
gray=cv2.cvtColor(img,cv2 .COLOR_BGR2GRAY)
thresh,binary=cv2.threshold(gray,1255,cv2 .THRESH_BINARY)
x=0
y=0
h,w=binary.shape
topdot=findEdgeDot(binary,x,x w-1,y,y)
botdot=findEdgeDot(二进制,x,x w-1,y h-1,y h-1)
lefdot=findEdgeDot(二进制,x,x,y,y h-1)
rigdot=findEdgeDot(二进制,x w-1,x w-1,y,y h-1)
edgedot=[topdot,botdot,lefdot,rigdot]
而topdot或botdot或勒夫多特或rigdot:
maxedge=max(edgedot)
如果maxedge==topdot:
y=步长
h -=步长
elif maxedge==botdot:
h -=步长
elif maxedge==lefdot:
x=步长
w -=步长
否则:
w -=步长
topdot=findEdgeDot(binary,x,x w-1,y,y)
botdot=findEdgeDot(二进制,x,x w-1,y h-1,y h-1)
lefdot=findEdgeDot(二进制,x,x,y,y h-1)
rigdot=findEdgeDot(二进制,x w-1,x w-1,y,y h-1)
edgedot=[topdot,botdot,lefdot,rigdot]
返回x,y,w,h
定义合并(img1,img2,sift,flann):
srcImg,img1gray=imgProcess(img1,img1.shape[0]//2,img1.shape[0]//2,img1.shape[1]//2,img1.shape[1]//2)
testImg,img2gray=imgProcess(img2,img2.shape[0]//2,img2.shape[0]//2,img2.shape[1]//2,img2.shape[1]//2)
#使用撒查找关键点和描述符
kp1,des 1=sift。检测和计算(img 1灰色,无)
kp2,des 2=sift。检测和计算(img 2灰色,无)
#弗兰参数
matches=flann.knnMatch(des1,des2,k=2)
#只需要绘制好的匹配,所以创建一个遮罩
matchesMask=[[0,0] for i in range(len(matches))]
好=[]
pts1=[]
pts2=[]
#根据劳氏文件进行比率测试
对于我,(男,女)在枚举(匹配):
如果m。距离为0.7*n。距离:
好的。追加(m)
pts2.append(kp2[m.trainIdx].pt)
pts1.append(kp1[m.queryIdx].pt)
matchesMask[i]=[1,0]
# draw _ params=dict(match color=(0,255,0),
# singlePointColor=(255,0,0),
# matchesMask=matchesMask,
# flags=0)
# img 3=cv2。drawmatchesknn(img 1 gray,kp1,img2gray,kp2,matches,None,**draw_params)
rows,cols=srcImg.shape[:2]
最小匹配计数=10
如果伦(好)最小匹配计数:
src _ pts=NP。float 32([kp1[m . query idx].元素铂的符号为我很好.整形(-1,1,2)
dst _ pts=NP。浮动32([kp2[m . traini dx].元素铂的符号为我很好.整形(-1,1,2)
m,mask=cv2。发现单应性(src_pts,dst_pts,cv2 .RANSAC,5.0)
war pimg=cv2。warp perspective(testImg,np.array(M),(testImg.shape[0]*2,testImg.shape[1]*2),flags=cv2 .WARP_INVERSE_MAP)
方向=-1
#重叠区域
对于范围内的列(0,列):
if srcImg[:col].任何()和warpImg[:col].any():
左=列
破裂
if srcImg[:left-1].any():
方向=向左方向
否则:
方向=右方向
对于范围内的列(列-1,0,-1):
if srcImg[:col].任何()和warpImg[:col].any():
右=列
破裂
#获取最大区域
res=np.zeros([rows,cols,3],np.uint8)
对于范围内的行(0,行):
对于范围内的列(0,列):
如果不是行,列.any():
res[row,col]=warpImg[row,col]
elif not warp ing[row,col].any():
res[row,col]=srcImg[row,col]
否则:
srcImgLen=float(abs(col - left))
testImgLen=float(abs(col - right))
alpha=1-srcImgLen/(srcImgLen testImgLen)#离得越近权重越大
如果方向==左方向:
阿尔法=1-阿尔法
res[row,col]=np.clip(srcImg[row,col] * (1-alpha) warpImg[row,col] * alpha,0,255)
# opencv是matplotlib是rgb
x,y,w,h=getsmallouterect(RES)
resImg=res[y:y h,x:x w]
x,y,w,h=getMaxInnerRect(resImg,2)
outimg=resImg[y:y h,x:x w]
return (True,resImg,outimg)
#res=cv2.cvtColor(res,cv2 .COLOR_BGR2RGB)
#展示结果
# plt。图()
# plt.imshow(分辨率)
# plt.show()
否则:
返回(假)
if __name__==__main__ :
img1=cv2.imread(./img/test1.jpg )
img2=cv2.imread(./img/test2.jpg )
sift,flann=getMachine()
res=mergeImge(img1,img2,sift,flann)
if(res[0]):
cv2.imshow(res ,res[2])
cv2.waitKey()GUI界面图形用户界面
导入系统
导入cv2
从合并图片导入合并图片,获取机器
来自PyQt5 .QtWidgets导入QApplication,QPushButton,QFileDialog,QMainWindow,QMessageBox,QLabel
来自PyQt5 .模块导入QIcon、QImage、QPixmap
myGUI类(QMainWindow):
def __init__(self):
超级()。__init__()
self.img1=无
self.img2=无
self.outimg=无
self.outimg_state=0
self.imgNum=0
self.sift,self.flann=getMachine()
self.initUI()
def initUI(self):
self.setFixedSize(1000,800)
self.setWindowTitle(图像合并)
#self.statusBar()
self.setWindowIcon(QIcon(./source/imgsrc/icon.png ))
self.imglbl=QLabel(self)
#自我。LBL国际管理集团。setscaledcontents(True)
self.imglbl.resize(900,700)
self.imglbl.move(50,50)
choiceImg=QPushButton(加载图片,自我)
choiceImg.setFixedSize(100,50)
选择img。移动((1000//3-100)//2,30)
选择img。点击了。连接(自我。openfile)
mergeImg=QPushButton(拼接图片,自我)
mergeImg.setFixedSize(100,50)
合并img。移动((1000//3-100)//2 1000//3,30)
合并img。点击了。连接(自我。合并)
saveImg=QPushButton(保存图片,自我)
saveImg.setFixedSize(100,50)
保存img。移动((1000//3-100)//2 1000//3 * 2,30)
保存img。点击了。连接(自我。保存文件)
self.statusBar().showMessage(请加载图片!)
self.show()
定义保存文件(自身):
if self.outimg_state:
filter=Images (* .jpg);图像(*。BMP);图像(*。 png)
fname=qfiledialog。getsave filename(self, Save file , ./output/,筛选器)
cv2.imwrite(fname[0],self.outimg)
否则:
self.statusBar().showMessage(没有拼接成功的图片!)
定义合并(自身):
如果self.imgNum==2:
self.statusBar().showMessage(正在拼接中,请耐心等待~~~)
QApplication.processEvents()
res=mergeImge(self.img1,self.img2,self.sift,self.flann)
self.img2=无
如果不是res[0]:
self.statusBar().showMessage(没有足够的特征点,拼接失败!)
self.imgNum=0
self.img1=无
否则:
self.imgNum=1
self.img1=res[1]
self.outimg=res[2]
outimg=self.outimg.copy()
self.outimg_state=1
if outimg.shape[1] 900:
outimg=cv2.resize(outimg,(900,int(900/outi mg。shape[1]* outi mg。形状[0]))
if outimg.shape[0] 700:
outimg=cv2.resize(outimg,(int(700/outi mg。shape[0]* outi mg。形状[1]),700)
imgrgb=cv2.cvtColor(outimg,cv2 .COLOR_BGR2RGB)
w=imgrgb.shape[1] #获取图像大小
h=imgrgb.shape[0]
frame=QImage(imgrgb.data,w,h,w*3,QImage .格式_RGB888)
pix=QPixmap.fromImage(帧)
self.imglbl.setPixmap (pix)
self.statusBar().showMessage(继续拼接-请加载新的图片)
否则:
self.statusBar().showMessage(图片数量不足,请继续添加.)
def openFile(自身):
fname=qfiledialog。获取打开文件名(self,选择图像, ./img/)
如果不是self.imgNum:
self.img1=cv2.imread(fname[0])
如果self.img1为无:
self.statusBar().showMessage(加载图片失败,请重新选择!)
Qmessagebox.warning (self, warning ,无效图片!)
否则:
self.imgNum=1
Self.statusBar()。showMessage(“需要再加载一张图片”)
elif self.imgNum==1:
self.img2=cv2.imread(fname[0])
如果self.img2为None:
Self.statusBar()。showMessage(加载图片失败,请重新选择!)
Qmessagebox.warning (self, warning ,无效图片!)
否则:
self.imgNum=1
Self.statusBar()。showMessage(已经加载了两张图片,可以拼接了!)
if __name__==__main__ :
app=QA application(sys . argv)
ex=myGUI()
Sys.exit(app.exec_())结果显示原图。
结果,两块2。3块拼接在一起。
风暴中的白杨
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。