Python 实现 深度学习图片爬虫、以及批量处理工具
来源:互联网 发布:手机自定义抽奖软件 编辑:程序博客网 时间:2024/06/05 11:00
主要是作为深度学习Caffe SSD 数据预训练的工具
第一步 实现 爬虫(hexie)
这里 主要参考了 github 上的 大神的代码 二次开发,使用了多线程。
respect
http://lovenight.github.io/2015/11/15/Python-3-%E5%A4%9A%E7%BA%BF%E7%A8%8B%E4%B8%8B%E8%BD%BD%E7%99%BE%E5%BA%A6%E5%9B%BE%E7%89%87%E6%90%9C%E7%B4%A2%E7%BB%93%E6%9E%9C/
第二步 实现照片批处理
首先是界面UI使用 QT design 设计
mainwindow.ui
<?xml version="1.0" encoding="UTF-8"?><ui version="4.0"> <class>MainWindow</class> <widget class="QMainWindow" name="MainWindow"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>1400</width> <height>900</height> </rect> </property> <property name="minimumSize"> <size> <width>1400</width> <height>900</height> </size> </property> <property name="maximumSize"> <size> <width>1400</width> <height>900</height> </size> </property> <property name="windowTitle"> <string>MainWindow</string> </property> <widget class="QWidget" name="centralWidget"> <widget class="QWidget" name="verticalLayoutWidget_2"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>1391</width> <height>821</height> </rect> </property> <layout class="QVBoxLayout" name="verticalLayout_2" stretch="2,1,1,1,16"> <item> <layout class="QHBoxLayout" name="horizontalLayout_2" stretch="1,1,10,2,2,0"> <item> <spacer name="horizontalSpacer_4"> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> <property name="sizeType"> <enum>QSizePolicy::Maximum</enum> </property> <property name="sizeHint" stdset="0"> <size> <width>30</width> <height>20</height> </size> </property> </spacer> </item> <item> <widget class="QLabel" name="label_10"> <property name="minimumSize"> <size> <width>40</width> <height>40</height> </size> </property> <property name="text"> <string> PATH :</string> </property> </widget> </item> <item> <widget class="QLineEdit" name="lineEdit"> <property name="minimumSize"> <size> <width>40</width> <height>50</height> </size> </property> </widget> </item> <item> <widget class="QPushButton" name="scanButton"> <property name="minimumSize"> <size> <width>40</width> <height>50</height> </size> </property> <property name="styleSheet"> <string notr="true"/> </property> <property name="text"> <string>Scan</string> </property> </widget> </item> <item> <widget class="QPushButton" name="loadButton"> <property name="minimumSize"> <size> <width>40</width> <height>50</height> </size> </property> <property name="text"> <string>Load</string> </property> </widget> </item> <item> <spacer name="horizontalSpacer_3"> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> <property name="sizeType"> <enum>QSizePolicy::Maximum</enum> </property> <property name="sizeHint" stdset="0"> <size> <width>30</width> <height>20</height> </size> </property> </spacer> </item> </layout> </item> <item> <spacer name="verticalSpacer_15"> <property name="orientation"> <enum>Qt::Vertical</enum> </property> <property name="sizeType"> <enum>QSizePolicy::Maximum</enum> </property> <property name="sizeHint" stdset="0"> <size> <width>20</width> <height>5</height> </size> </property> </spacer> </item> <item> <layout class="QHBoxLayout" name="horizontalLayout_9"> <item> <spacer name="horizontalSpacer_7"> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> <property name="sizeType"> <enum>QSizePolicy::Maximum</enum> </property> <property name="sizeHint" stdset="0"> <size> <width>30</width> <height>20</height> </size> </property> </spacer> </item> <item> <widget class="QLabel" name="infoLabel"> <property name="styleSheet"> <string notr="true">background-color: rgb(211, 215, 207);</string> </property> <property name="text"> <string>TextLabel</string> </property> </widget> </item> <item> <spacer name="horizontalSpacer_8"> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> <property name="sizeType"> <enum>QSizePolicy::Maximum</enum> </property> <property name="sizeHint" stdset="0"> <size> <width>30</width> <height>20</height> </size> </property> </spacer> </item> </layout> </item> <item> <spacer name="verticalSpacer"> <property name="orientation"> <enum>Qt::Vertical</enum> </property> <property name="sizeType"> <enum>QSizePolicy::Maximum</enum> </property> <property name="sizeHint" stdset="0"> <size> <width>20</width> <height>5</height> </size> </property> </spacer> </item> <item> <layout class="QHBoxLayout" name="horizontalLayout_4"> <item> <spacer name="horizontalSpacer_6"> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> <property name="sizeType"> <enum>QSizePolicy::Maximum</enum> </property> <property name="sizeHint" stdset="0"> <size> <width>30</width> <height>20</height> </size> </property> </spacer> </item> <item> <layout class="QVBoxLayout" name="verticalLayout" stretch="16,1"> <item> <layout class="QGridLayout" name="imgLayout"> <item row="0" column="0"> <widget class="QLabel" name="label0"> <property name="text"> <string/> </property> </widget> </item> </layout> </item> <item> <layout class="QHBoxLayout" name="horizontalLayout_3"> <item> <spacer name="horizontalSpacer_2"> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> <property name="sizeType"> <enum>QSizePolicy::Maximum</enum> </property> <property name="sizeHint" stdset="0"> <size> <width>10</width> <height>20</height> </size> </property> </spacer> </item> <item> <widget class="QLabel" name="label_11"> <property name="text"> <string>Process</string> </property> </widget> </item> <item> <widget class="QProgressBar" name="progressBar"> <property name="minimumSize"> <size> <width>0</width> <height>40</height> </size> </property> <property name="maximumSize"> <size> <width>166666</width> <height>40</height> </size> </property> <property name="value"> <number>24</number> </property> </widget> </item> <item> <spacer name="horizontalSpacer_9"> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> <property name="sizeType"> <enum>QSizePolicy::Maximum</enum> </property> <property name="sizeHint" stdset="0"> <size> <width>20</width> <height>20</height> </size> </property> </spacer> </item> </layout> </item> </layout> </item> <item> <layout class="QGridLayout" name="gridLayout"> <item row="1" column="0"> <widget class="QPushButton" name="startButton"> <property name="minimumSize"> <size> <width>200</width> <height>60</height> </size> </property> <property name="maximumSize"> <size> <width>200</width> <height>60</height> </size> </property> <property name="text"> <string>START</string> </property> </widget> </item> <item row="17" column="0"> <widget class="QPushButton" name="addButton"> <property name="minimumSize"> <size> <width>200</width> <height>50</height> </size> </property> <property name="maximumSize"> <size> <width>200</width> <height>50</height> </size> </property> <property name="text"> <string>BIGGER</string> </property> </widget> </item> <item row="15" column="0"> <layout class="QHBoxLayout" name="horizontalLayout"> <item> <widget class="QPushButton" name="SButton"> <property name="minimumSize"> <size> <width>60</width> <height>60</height> </size> </property> <property name="maximumSize"> <size> <width>60</width> <height>60</height> </size> </property> <property name="text"> <string>S</string> </property> </widget> </item> <item> <widget class="QPushButton" name="MButton"> <property name="minimumSize"> <size> <width>60</width> <height>60</height> </size> </property> <property name="maximumSize"> <size> <width>60</width> <height>60</height> </size> </property> <property name="text"> <string>M</string> </property> </widget> </item> <item> <widget class="QPushButton" name="LButton"> <property name="minimumSize"> <size> <width>60</width> <height>60</height> </size> </property> <property name="maximumSize"> <size> <width>60</width> <height>60</height> </size> </property> <property name="text"> <string>L</string> </property> </widget> </item> </layout> </item> <item row="11" column="0"> <widget class="QPushButton" name="saveButton"> <property name="minimumSize"> <size> <width>200</width> <height>60</height> </size> </property> <property name="maximumSize"> <size> <width>200</width> <height>60</height> </size> </property> <property name="text"> <string>SAVE</string> </property> </widget> </item> <item row="18" column="0"> <spacer name="verticalSpacer_11"> <property name="orientation"> <enum>Qt::Vertical</enum> </property> <property name="sizeType"> <enum>QSizePolicy::Maximum</enum> </property> <property name="sizeHint" stdset="0"> <size> <width>20</width> <height>15</height> </size> </property> </spacer> </item> <item row="12" column="0"> <spacer name="verticalSpacer_9"> <property name="orientation"> <enum>Qt::Vertical</enum> </property> <property name="sizeType"> <enum>QSizePolicy::Maximum</enum> </property> <property name="sizeHint" stdset="0"> <size> <width>20</width> <height>15</height> </size> </property> </spacer> </item> <item row="5" column="0"> <widget class="QPushButton" name="startButton_2"> <property name="minimumSize"> <size> <width>200</width> <height>60</height> </size> </property> <property name="maximumSize"> <size> <width>200</width> <height>60</height> </size> </property> <property name="text"> <string>NEXT</string> </property> </widget> </item> <item row="2" column="0"> <spacer name="verticalSpacer_14"> <property name="orientation"> <enum>Qt::Vertical</enum> </property> <property name="sizeType"> <enum>QSizePolicy::Maximum</enum> </property> <property name="sizeHint" stdset="0"> <size> <width>20</width> <height>15</height> </size> </property> </spacer> </item> <item row="11" column="1"> <spacer name="horizontalSpacer"> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> <property name="sizeType"> <enum>QSizePolicy::Maximum</enum> </property> <property name="sizeHint" stdset="0"> <size> <width>30</width> <height>20</height> </size> </property> </spacer> </item> <item row="8" column="0"> <spacer name="verticalSpacer_3"> <property name="orientation"> <enum>Qt::Vertical</enum> </property> <property name="sizeType"> <enum>QSizePolicy::Maximum</enum> </property> <property name="sizeHint" stdset="0"> <size> <width>20</width> <height>15</height> </size> </property> </spacer> </item> <item row="3" column="0"> <widget class="QPushButton" name="stopButton"> <property name="minimumSize"> <size> <width>200</width> <height>60</height> </size> </property> <property name="maximumSize"> <size> <width>200</width> <height>60</height> </size> </property> <property name="text"> <string>STOP</string> </property> </widget> </item> <item row="7" column="0"> <widget class="QPushButton" name="lastButton"> <property name="minimumSize"> <size> <width>200</width> <height>60</height> </size> </property> <property name="maximumSize"> <size> <width>200</width> <height>60</height> </size> </property> <property name="text"> <string>LAST</string> </property> </widget> </item> <item row="19" column="0"> <widget class="QPushButton" name="jianButton"> <property name="minimumSize"> <size> <width>200</width> <height>50</height> </size> </property> <property name="maximumSize"> <size> <width>200</width> <height>50</height> </size> </property> <property name="text"> <string>SMALLER</string> </property> </widget> </item> <item row="16" column="0"> <spacer name="verticalSpacer_10"> <property name="orientation"> <enum>Qt::Vertical</enum> </property> <property name="sizeType"> <enum>QSizePolicy::Maximum</enum> </property> <property name="sizeHint" stdset="0"> <size> <width>20</width> <height>15</height> </size> </property> </spacer> </item> <item row="14" column="0"> <spacer name="verticalSpacer_13"> <property name="orientation"> <enum>Qt::Vertical</enum> </property> <property name="sizeType"> <enum>QSizePolicy::Maximum</enum> </property> <property name="sizeHint" stdset="0"> <size> <width>20</width> <height>15</height> </size> </property> </spacer> </item> <item row="13" column="0"> <widget class="QPushButton" name="pushButton"> <property name="minimumSize"> <size> <width>200</width> <height>60</height> </size> </property> <property name="maximumSize"> <size> <width>200</width> <height>60</height> </size> </property> <property name="text"> <string>PLAY</string> </property> </widget> </item> <item row="6" column="0"> <spacer name="verticalSpacer_12"> <property name="orientation"> <enum>Qt::Vertical</enum> </property> <property name="sizeType"> <enum>QSizePolicy::Maximum</enum> </property> <property name="sizeHint" stdset="0"> <size> <width>20</width> <height>15</height> </size> </property> </spacer> </item> <item row="0" column="0"> <spacer name="verticalSpacer_2"> <property name="orientation"> <enum>Qt::Vertical</enum> </property> <property name="sizeType"> <enum>QSizePolicy::Maximum</enum> </property> <property name="sizeHint" stdset="0"> <size> <width>20</width> <height>40</height> </size> </property> </spacer> </item> <item row="4" column="0"> <spacer name="verticalSpacer_4"> <property name="orientation"> <enum>Qt::Vertical</enum> </property> <property name="sizeType"> <enum>QSizePolicy::Maximum</enum> </property> <property name="sizeHint" stdset="0"> <size> <width>20</width> <height>15</height> </size> </property> </spacer> </item> </layout> </item> </layout> </item> </layout> </widget> </widget> <widget class="QMenuBar" name="menuBar"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>1400</width> <height>25</height> </rect> </property> <widget class="QMenu" name="menuEDIT"> <property name="title"> <string>EDIT</string> </property> </widget> <widget class="QMenu" name="menuRDS"> <property name="title"> <string>RDS</string> </property> </widget> <addaction name="menuEDIT"/> <addaction name="menuRDS"/> </widget> <widget class="QToolBar" name="mainToolBar"> <attribute name="toolBarArea"> <enum>TopToolBarArea</enum> </attribute> <attribute name="toolBarBreak"> <bool>false</bool> </attribute> </widget> <widget class="QStatusBar" name="statusBar"/> </widget> <layoutdefault spacing="6" margin="11"/> <resources/> <connections/></ui>
执行 如下命令:
pyuic4 mainwindow.ui >tform.py
接下来是pyqt4 的程序开发
主要实现了如下功能:
1、批处理 删除 重命名 大小缩放 翻页
2、照片自动播放预览
#coding=utf-8import sysfrom PyQt4.QtCore import *from tform import *from PyQt4.QtGui import *import osqtCreatorFile = "zhixi.py" # Enter file here.#Ui_MainWindow, QtBaseClass = uic.loadUiType(qtCreatorFile)import time#static parameterstateButton=0deleteList=[]class MyLabel(QLabel): def __init__(self,st): super(MyLabel,self).__init__(None) #self.setText(a) self.st=st self.clickButton=0 #global lis global stateButton def setB(self,st1): self.st=st1 self.clickButton=0 if self.st in deleteList: self.setFrameShape (QFrame.Box) self.setStyleSheet("border: 3px solid #ff0000") self.clickButton=1 else: self.setFrameShape (QFrame.Box) self.setStyleSheet("") ''' def mousePressEvent(self, e):##重载一下鼠标事件 #print "you clicked the label" pass ''' #def mouseReleaseEvent(self, QMouseEvent): def mousePressEvent(self, QMouseEvent): if stateButton==1: self.clickButton=1-self.clickButton if self.clickButton==1: self.setFrameShape (QFrame.Box) self.setStyleSheet("border: 3px solid #ff0000") if self.st not in deleteList: deleteList.append(self.st) else: pass else: #self.setFrameShape (QFrame.Box) self.setStyleSheet("") if self.st in deleteList: deleteList.remove(self.st) else: pass elif stateButton==0: pass print "name",self.st,deleteList,self.clickButtonclass MyApp(QtGui.QMainWindow): def __init__(self): QtGui.QMainWindow.__init__(self) self.ui=Ui_MainWindow() self.ui.setupUi(self) self.ui.infoLabel.setText('aaa') self.a=0 self.imgLen=0 self.imgBegin=0 self.imgEnd=0 self.imgPage=0 self.avNum=0 self.currentPage=1 self.filename="" self.rate=None self.sizeW=3 self.sizeH=2 self.play=0 self.ui.scanButton.clicked.connect(self.openFileDirectory) self.ui.loadButton.clicked.connect(self.loadFile) self.ui.startButton.clicked.connect(self.start) self.ui.stopButton.clicked.connect(self.stop) self.ui.saveButton.clicked.connect(self.saveFile) self.ui.startButton_2.clicked.connect(self.nextPage) self.ui.lastButton.clicked.connect(self.lastPage) self.ui.jianButton.clicked.connect(self.smaller) self.ui.addButton.clicked.connect(self.bigger) self.ui.SButton.clicked.connect(self.SSize) self.ui.MButton.clicked.connect(self.MSize) self.ui.LButton.clicked.connect(self.LSize) self.ui.pushButton.clicked.connect(self.playPhoto) self.imglist=[] self.labelList=[] self.setProgress() def openFileDirectory(self): f_name = QFileDialog.getExistingDirectory(self,"Please choose file directory","./") ##"open file Dialog "文件对话框的标题,第二个是打开的默认路径,第三个是文件类型 self.filename=self.QString2PyString(f_name) self.ui.lineEdit.setText(self.filename) def start(self): global stateButton stateButton=1 self.play=0 self.ui.startButton.setEnabled(True) self.ui.pushButton.setEnabled(False) def stop(self): global stateButton stateButton=0 self.play=0 self.ui.pushButton.setEnabled(True) self.ui.startButton.setEnabled(True) self.ui.startButton_2.setEnabled(True) self.ui.lastButton.setEnabled(True) self.ui.saveButton.setEnabled(True) #self.ui.startButton.setEnabled(False) def loadFile(self): self.imglist=[] self.saveFile() self.imgLen=len(self.imglist) self.calNum() self.setLay() self.setPhoto() self.setInfo() self.setProgress() def calNum(self): self.avNum=self.sizeW*self.sizeH if self.imgLen%(self.sizeW*self.sizeH)>0: self.imgPage=int(self.imgLen/(self.sizeW*self.sizeH))+1 else: self.imgPage=self.imgLen/(self.sizeW*self.sizeH) self.imgBegin=0 self.currentPage=1 self.imgEnd=max(min(self.avNum-1,self.imgLen-1),0) #print self.imgPage def nextPage(self): if self.currentPage==self.imgPage: self.WarnS(" Now is max Page ") else: print self.currentPage if self.currentPage+1<=self.imgPage: self.currentPage+=1 self.imgBegin=max(min(self.avNum+self.imgBegin,self.imgLen-1),0) self.imgEnd=max(min(self.imgBegin+self.avNum-1,self.imgLen-1),0) print self.imgBegin,self.imgEnd,self.imgPage self.setInfo() self.setProgress() self.setPhoto() def lastPage(self): if self.currentPage==1: self.WarnS(" Now is 1 Page ") else: print self.currentPage if self.currentPage-1>0: self.currentPage-=1 self.imgBegin=max(self.imgBegin-self.avNum,0) self.imgEnd=max(min(self.imgBegin+self.avNum-1,self.imgLen),0) self.setInfo() self.setProgress() self.setPhoto() def playPhoto(self): global stateButton stateButton=0 self.play=1 self.calNum() self.currentPage=1 self.ui.pushButton.setEnabled(True) self.ui.startButton.setEnabled(False) self.ui.startButton_2.setEnabled(False) self.ui.lastButton.setEnabled(False) self.ui.saveButton.setEnabled(False) for i in range(1,self.imgPage): time.sleep(1) self.nextPage() def QString2PyString(self, qStr): # # QString,如果内容是中文,则直接使用会有问题,要转换成 python string return unicode(qStr.toUtf8(), 'utf-8', 'ignore') def setPhoto(self): #if self.imgEnd==self.imgLen: if self.imgLen==0: self.WarnS(" NO photo angmore ") else: for j in range(0,self.avNum): self.labelList[j].setText(" ") self.labelList[j].setB(" 0 ") for i in range(self.imgBegin,self.imgEnd+1): s1=self.filename+'/'+self.imglist[i] self.labelList[i-self.imgBegin].setPixmap(QPixmap(s1)) self.labelList[i-self.imgBegin].setB(self.imglist[i]) ''' else: for j in range(0,self.avNum): self.labelList[j].setText(" ") for i in range(self.imgBegin,self.imgEnd+1): s1=self.filename+'/'+self.imglist[i] self.labelList[i-self.imgBegin].setPixmap(QPixmap(s1)) self.labelList[i-self.imgBegin].setB(self.imglist[i]) ''' def setLay(self): try: self.ui.imgLayout.removeWidget(label0) except: pass pos = [(x, y) for x in range(self.sizeH) for y in range(self.sizeW)] for p in range(0,len(self.labelList)): self.ui.imgLayout.removeWidget(self.labelList[p]) self.labelList[p].deleteLater() self.labelList=[] for i in range(len(pos)): label =MyLabel(str(i)) #label.setFrameShape (QFrame.Box) #label.setStyleSheet("border: 3px solid #ff0000") #label.setPixmap(QPixmap(s1)) self.labelList.append(label) self.ui.imgLayout.addWidget(label, pos[i][0], pos[i][1]) def setProgress(self): if self.imgEnd==0: self.ui.progressBar.setValue(0) else: self.ui.progressBar.setValue(min(int(float(1.0*self.imgEnd/(self.imgLen-1))*100),100)) def smaller(self): self.sizeW+=1 self.sizeH+=1 self.setLay() self.calNum() self.setPhoto() self.setInfo() self.setProgress() def bigger(self): self.sizeW=max(self.sizeW-1,1) self.sizeH=max(self.sizeH-1,1) self.setLay() self.calNum() self.setPhoto() self.setInfo() self.setProgress() def SSize(self): self.sizeW=8 self.sizeH+=6 self.setLay() self.calNum() self.setPhoto() self.setInfo() self.setProgress() def MSize(self): self.sizeW=4 self.sizeH=3 self.setLay() self.calNum() self.setPhoto() self.setInfo() self.setProgress() def LSize(self): self.sizeW=2 self.sizeH=1 self.setLay() self.calNum() self.setPhoto() self.setInfo() self.setProgress() def saveFile(self): #try: global deleteList if len(deleteList)==0: self.saveFile2() self.WarnS(" Load Succeed ") else: self.removeFile() self.saveFile2() deleteList=[] #deleteList=[] self.calNum() self.setLay() self.setPhoto() self.setInfo() self.setProgress() self.WarnS(" Save Succeed ") ''' except: self.WarnS(" Save Failed ") ''' def removeFile(self): filename=self.filename+'/' global deleteList bd=[] k=len(os.listdir(filename)) filenameC=filename+"rabbish" if os.path.exists(filenameC): pass else: os.mkdir(filenameC) for filestd in deleteList: if filestd[len(filestd)-3:len(filestd)]=='jpg' or filestd[len(filestd)-4:len(filestd)]=='jpeg' or filestd[len(filestd)-3:len(filestd)]=='png': bd.append(filestd) for i in range(0,len(bd)): k+=1 name2td=filename+bd[i] name2d=filename+'rabbish/'+str(k)+bd[i] #print name2td,name2d try: os.rename(name2td,name2d) except: pass def saveFile2(self): filename=self.filename+'/' #print filename files = os.listdir(filename) b=[] b2=[] for filestr in files: if filestr[len(filestr)-3:len(filestr)]=='jpg' or filestr[len(filestr)-4:len(filestr)]=='jpeg' or filestr[len(filestr)-3:len(filestr)]=='png': b.append(filestr) #print len(b) sx=sorted(b) #print sx filenameTemp=filename+"temp" if os.path.exists(filenameTemp): pass else: os.mkdir(filenameTemp) for i in range(0,len(b)): if i<10: si='00'+str(i) elif i<100: si='0'+str(i) elif i<1000: si=str(i) name2=filename+'temp/'+si+'.jpg' name1=filename+sx[i] #print name1,name2 b2.append(si+'.jpg') os.rename(name1,name2) for j in range(0,len(b2)): name22=filename+'temp/'+b2[j] name3=filename+b2[j] ''' try: ''' os.rename(name22,name3) ''' except: pass ''' os.rmdir(filenameTemp) self.imglist=b2 self.imgLen=len(self.imglist) print "imgLen",self.imgLen print self.imglist def setInfo(self): self.ui.infoLabel.setText(" OPEN: "+self.filename+" "+"TOTAL: "+str(self.imgLen)+" "+"Current: "+str(self.imgBegin)+" to "+str(self.imgEnd)+" "+"CurrentPage "+str(self.currentPage)+" "+" Total "+str(self.imgPage)) def WarnS(self,s): QMessageBox.information(self,QString.fromLocal8Bit("请确认"),QString.fromLocal8Bit(s)) if __name__ == "__main__": app = QtGui.QApplication(sys.argv) window = MyApp() window.show() print window.a sys.exit(app.exec_())
第三步 实现标注
最后是github 标注工具 bbox 的改进版本 主要改进了图像缩放转换和整体界面
#-------------------------------------------------------------------------------# Name: Object bounding box label tool# Purpose: Label object bboxes for ImageNet Detection data# Author: Qiushi# Created: 06/06/2014##-------------------------------------------------------------------------------from __future__ import divisionfrom Tkinter import *import tkMessageBoxfrom PIL import Image, ImageTkimport osimport globimport random# colors for the bboxesCOLORS = ['red', 'blue', 'yellow', 'pink', 'cyan', 'green', 'black']# image sizes for the examplesSIZE = 256, 256class LabelTool(): def __init__(self, master): # set up the main frame self.parent = master self.parent.title("LabelTool") self.frame = Frame(self.parent) self.frame.pack(fill=BOTH, expand=1) self.parent.resizable(width = FALSE, height = FALSE) # initialize global state self.imageDir = '' self.imageList= [] self.egDir = '' self.egList = [] self.outDir = '' self.cur = 0 self.total = 0 self.category = 0 self.imagename = '' self.labelfilename = '' self.img = Image.open('index.jpg') self.tkimg = ImageTk.PhotoImage(self.img) self.img2=None # initialize mouse state self.STATE = {} self.STATE['click'] = 0 self.STATE['x'], self.STATE['y'] = 0, 0 # reference to bbox self.bboxIdList = [] self.bboxId = None self.bboxList = [] self.hl = None self.vl = None self.k=0 # ----------------- GUI stuff --------------------- # dir entry & load self.label = Label(self.frame, text = "Image Dir:") self.label.grid(row = 0, column = 0, sticky = E) self.entry = Entry(self.frame) self.entry.grid(row = 0, column = 1, sticky = W+E) self.ldBtn = Button(self.frame, text = "Load", command = self.loadDir) self.ldBtn.grid(row = 0, column = 2, sticky = W+E) # main panel for labeling self.mainPanel = Canvas(self.frame, cursor='tcross') self.mainPanel.bind("<Button-1>", self.mouseClick) self.mainPanel.bind("<Motion>", self.mouseMove) self.parent.bind("<Escape>", self.cancelBBox) # press <Espace> to cancel current bbox self.parent.bind("s", self.cancelBBox) self.parent.bind("a", self.prevImage) # press 'a' to go backforward self.parent.bind("d", self.nextImage) # press 'd' to go forward self.mainPanel.grid(row = 1, column = 1, rowspan = 4, sticky = W+N) # showing bbox info & delete bbox self.lb1 = Label(self.frame, text = 'Bounding boxes:') self.lb1.grid(row = 1, column = 2, sticky = W+N) self.listbox = Listbox(self.frame, width = 22, height = 12) self.listbox.grid(row = 2, column = 2, sticky = N) self.btnDel = Button(self.frame, text = 'Delete', command = self.delBBox) self.btnDel.grid(row = 3, column = 2, sticky = W+E+N) self.btnClear = Button(self.frame, text = 'ClearAll', command = self.clearBBox) self.btnClear.grid(row = 4, column = 2, sticky = W+E+N) # control panel for image navigation self.ctrPanel = Frame(self.frame) self.ctrPanel.grid(row = 5, column = 1, columnspan = 2, sticky = W+E) self.prevBtn = Button(self.ctrPanel, text='<< Prev', width = 10, command = self.prevImage) self.prevBtn.pack(side = LEFT, padx = 5, pady = 3) self.nextBtn = Button(self.ctrPanel, text='Next >>', width = 10, command = self.nextImage) self.nextBtn.pack(side = LEFT, padx = 5, pady = 3) self.progLabel = Label(self.ctrPanel, text = "Progress: / ") self.progLabel.pack(side = LEFT, padx = 5) self.tmpLabel = Label(self.ctrPanel, text = "Go to Image No.") self.tmpLabel.pack(side = LEFT, padx = 5) self.idxEntry = Entry(self.ctrPanel, width = 5) self.idxEntry.pack(side = LEFT) self.goBtn = Button(self.ctrPanel, text = 'Go', command = self.gotoImage) self.goBtn.pack(side = LEFT) self.mainPanel.config(width = 800, height = 800) self.mainPanel.create_image(0, 0, image = self.tkimg, anchor=NW) # example pannel for illustration ''' self.egPanel = Frame(self.frame, border = 10) self.egPanel.grid(row = 1, column = 0, rowspan = 5, sticky = N) self.tmpLabel2 = Label(self.egPanel, text = "Examples:") self.tmpLabel2.pack(side = TOP, pady = 5) self.egLabels = [] for i in range(3): self.egLabels.append(Label(self.egPanel)) self.egLabels[-1].pack(side = TOP) ''' # display mouse position self.disp = Label(self.ctrPanel, text='') self.disp.pack(side = RIGHT) self.frame.columnconfigure(1, weight = 1) self.frame.rowconfigure(4, weight = 1) # for debugging## self.setImage()## self.loadDir() def loadDir(self, dbg = False): if not dbg: s = self.entry.get() self.parent.focus() self.category = int(s) else: s = r'D:\workspace\python\labelGUI'## if not os.path.isdir(s):## tkMessageBox.showerror("Error!", message = "The specified dir doesn't exist!")## return # get image list self.imageDir = os.path.join(r'./Images', '%03d' %(self.category)) imglist1= glob.glob(os.path.join(self.imageDir, '*.jpg')) imglist2= glob.glob(os.path.join(self.imageDir, '*.jpeg')) imglist3= glob.glob(os.path.join(self.imageDir, '*.JPEG')) imglist4= glob.glob(os.path.join(self.imageDir, '*.png')) self.imageList= imglist1+imglist2+imglist3+imglist4 if len(self.imageList) == 0: print 'No images found in the specified dir!' return # default to the 1st image in the collection self.cur = 1 self.total = len(self.imageList) # set up output dir self.outDir = os.path.join(r'./Labels', '%03d' %(self.category)) if not os.path.exists(self.outDir): os.mkdir(self.outDir) # load example bboxes ''' self.egDir = os.path.join(r'./Examples', '%03d' %(self.category)) if not os.path.exists(self.egDir): return filelist = glob.glob(os.path.join(self.egDir, '*.JPEG')) self.tmp = [] self.egList = [] random.shuffle(filelist) for (i, f) in enumerate(filelist): if i == 3: break im = Image.open(f) r = min(SIZE[0] / im.size[0], SIZE[1] / im.size[1]) new_size = int(r * im.size[0]), int(r * im.size[1]) self.tmp.append(im.resize(new_size, Image.ANTIALIAS)) self.egList.append(ImageTk.PhotoImage(self.tmp[-1])) self.egLabels[i].config(image = self.egList[-1], width = SIZE[0], height = SIZE[1]) ''' self.loadImage() print '%d images loaded from %s' %(self.total, s) def loadImage(self): # load image imagepath = self.imageList[self.cur - 1] self.img = Image.open(imagepath) w,h=self.img.size print w,h if w>h: self.k=float(800.0/w) print "w>h" img=self.img.resize((800,int(self.k*h))) else: print "w<h" self.k=float(800.0/h) img=self.img.resize((int(self.k*w),800)) self.tkimg = ImageTk.PhotoImage(img) #self.mainPanel.config(width = max(self.tkimg.width(), 800), height = max(self.tkimg.height(), 800)) self.mainPanel.config(width = 800, height = 800) self.mainPanel.create_image(0, 0, image = self.tkimg, anchor=NW) self.progLabel.config(text = "%04d/%04d" %(self.cur, self.total)) # load labels self.clearBBox() self.imagename = os.path.split(imagepath)[-1].split('.')[0] labelname = self.imagename + '.txt' self.labelfilename = os.path.join(self.outDir, labelname) bbox_cnt = 0 if os.path.exists(self.labelfilename): with open(self.labelfilename) as f: for (i, line) in enumerate(f): if i == 0: bbox_cnt = int(line.strip()) continue tmp = [int(t.strip()) for t in line.split()]## print tmp self.bboxList.append(tuple(tmp)) tmpId = self.mainPanel.create_rectangle(tmp[0]*self.k, tmp[1]*self.k, \ tmp[2]*self.k, tmp[3]*self.k, \ width = 2, \ outline = COLORS[(len(self.bboxList)-1) % len(COLORS)]) self.bboxIdList.append(tmpId) self.listbox.insert(END, '(%d, %d) -> (%d, %d)' %(tmp[0], tmp[1], tmp[2], tmp[3])) self.listbox.itemconfig(len(self.bboxIdList) - 1, fg = COLORS[(len(self.bboxIdList) - 1) % len(COLORS)]) def saveImage(self): with open(self.labelfilename, 'w') as f: f.write('%d\n' %len(self.bboxList)) for bbox in self.bboxList: f.write(' '.join(map(str, bbox)) + '\n') print 'Image No. %d saved' %(self.cur) def mouseClick(self, event): if self.STATE['click'] == 0: self.STATE['x'], self.STATE['y'] = event.x, event.y else: x1, x2 = min(self.STATE['x'], event.x), max(self.STATE['x'], event.x) y1, y2 = min(self.STATE['y'], event.y), max(self.STATE['y'], event.y) self.bboxList.append((int(x1/self.k), int(y1/self.k), int(x2/self.k), int(y2/self.k))) self.bboxIdList.append(self.bboxId) self.bboxId = None self.listbox.insert(END, '(%d, %d) -> (%d, %d)' %(x1, y1, x2, y2)) self.listbox.itemconfig(len(self.bboxIdList) - 1, fg = COLORS[(len(self.bboxIdList) - 1) % len(COLORS)]) self.STATE['click'] = 1 - self.STATE['click'] def mouseMove(self, event): self.disp.config(text = 'k: %.2f x: %d y: %d' %(self.k,event.x, event.y)) if self.tkimg: if self.hl: self.mainPanel.delete(self.hl) self.hl = self.mainPanel.create_line(0, event.y, self.tkimg.width(), event.y, width = 2) if self.vl: self.mainPanel.delete(self.vl) self.vl = self.mainPanel.create_line(event.x, 0, event.x, self.tkimg.height(), width = 2) if 1 == self.STATE['click']: if self.bboxId: self.mainPanel.delete(self.bboxId) self.bboxId = self.mainPanel.create_rectangle(self.STATE['x'], self.STATE['y'], \ event.x, event.y, \ width = 2, \ outline = COLORS[len(self.bboxList) % len(COLORS)]) def cancelBBox(self, event): if 1 == self.STATE['click']: if self.bboxId: self.mainPanel.delete(self.bboxId) self.bboxId = None self.STATE['click'] = 0 def delBBox(self): sel = self.listbox.curselection() if len(sel) != 1 : return idx = int(sel[0]) self.mainPanel.delete(self.bboxIdList[idx]) self.bboxIdList.pop(idx) self.bboxList.pop(idx) self.listbox.delete(idx) def clearBBox(self): for idx in range(len(self.bboxIdList)): self.mainPanel.delete(self.bboxIdList[idx]) self.listbox.delete(0, len(self.bboxList)) self.bboxIdList = [] self.bboxList = [] def prevImage(self, event = None): self.saveImage() if self.cur > 1: self.cur -= 1 self.loadImage() def nextImage(self, event = None): self.saveImage() if self.cur < self.total: self.cur += 1 self.loadImage() def gotoImage(self): idx = int(self.idxEntry.get()) if 1 <= idx and idx <= self.total: self.saveImage() self.cur = idx self.loadImage()## def setImage(self, imagepath = r'test2.png'):## self.img = Image.open(imagepath)## self.tkimg = ImageTk.PhotoImage(self.img)## self.mainPanel.config(width = self.tkimg.width())## self.mainPanel.config(height = self.tkimg.height())## self.mainPanel.create_image(0, 0, image = self.tkimg, anchor=NW)if __name__ == '__main__': root = Tk() tool = LabelTool(root) root.resizable(width = True, height = True) root.mainloop()
阅读全文
0 0
- Python 实现 深度学习图片爬虫、以及批量处理工具
- python 爬虫批量下载图片
- python批量图片处理
- python实现图片爬虫
- 【Python】网络爬虫-批量下载图片
- python图片批量处理缩放
- 【python爬虫】百度贴吧帖子图片批量保存爬虫
- Python实现简单爬虫功能--批量下载百度贴吧里的图片
- Python爬虫的小白学习笔记1-批量下载图片
- python-框架-网页爬虫-文本处理-科学计算-可视化-机器学习-数据挖掘-深度学习
- python爬虫学习--下载图片
- python PIL 批量处理处理图片
- 【Python开发】【神经网络与深度学习】网络爬虫之图片自动下载器
- python开启摄像头以及深度学习实现目标检测
- 【Python开发】【神经网络与深度学习】网络爬虫之python实现
- Python + pyqt5 图片批量缩放工具
- python批量处理图片命名问题
- cv2 python 图片的批量处理
- Android动画效果之Frame Animation(逐帧动画)
- 详解java设计模式
- 技术文章 | 如何避免数据库“勒索事件”和“从删库到跑路”的尴尬
- EventBus源码分析(四): 发送Event和响应注册的回调方法
- java.sql.SQLException: Access denied for user 'è‘??????“'@'localhost' (using password: YES)
- Python 实现 深度学习图片爬虫、以及批量处理工具
- xpath
- Schlumberger.ECLIPSE.2014.1安装提示password failed check flexlm..报错解决方法
- Python3学习(23)--__slots__ 限制实例属性的绑定
- Elasticsearch之文档。
- Spring Boot 实例通过接口安全退出
- hdu 6183 Color it(变种线段树)
- Server端判别客户端访问的客户端类型
- iOS----解析网络json