亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Python編寫一個(gè)驗(yàn)證碼圖片數(shù)據(jù)標(biāo)注GUI程序附源碼

 更新時(shí)間:2019年12月09日 10:19:28   作者:州的先生  
這篇文章主要介紹了Python編寫一個(gè)驗(yàn)證碼圖片數(shù)據(jù)標(biāo)注GUI程序,本文給大家附上小編精心整理的源碼,需要的朋友可以參考下

做驗(yàn)證碼圖片的識(shí)別,不論是使用傳統(tǒng)的ORC技術(shù),還是使用統(tǒng)計(jì)機(jī)器學(xué)習(xí)或者是使用深度學(xué)習(xí)神經(jīng)網(wǎng)絡(luò),都少不了從網(wǎng)絡(luò)上采集大量相關(guān)的驗(yàn)證碼圖片做數(shù)據(jù)集樣本來(lái)進(jìn)行訓(xùn)練。

采集驗(yàn)證碼圖片,可以直接使用Python進(jìn)行批量下載,下載完之后,就需要對(duì)下載下來(lái)的驗(yàn)證碼圖片進(jìn)行標(biāo)注。一般情況下,一個(gè)驗(yàn)證碼圖片的文件名就是圖片中驗(yàn)證碼的實(shí)際字符串。

在不借助工具的情況下,我們對(duì)驗(yàn)證碼圖片進(jìn)行上述標(biāo)注的流程是:

1、打開(kāi)圖片所在的文件夾;
2、選擇一個(gè)圖片;
3、鼠標(biāo)右鍵重命名;
4、輸入正確的字符串;
5、保存

州的先生親身體驗(yàn),一個(gè)驗(yàn)證碼完成數(shù)據(jù)的標(biāo)注,大概需要10到20秒。大量的時(shí)間浪費(fèi)在了重復(fù)地進(jìn)行鼠標(biāo)右鍵重命名操作了。于是,使用Qt的Python封裝包——PyQt5,編寫了一個(gè)小工具,方便進(jìn)行驗(yàn)證碼圖片的數(shù)據(jù)標(biāo)注,節(jié)省時(shí)間,珍惜生命。

程序的運(yùn)行如下動(dòng)圖所示:

下面我們來(lái)了解一下如何編寫這個(gè)驗(yàn)證碼圖片數(shù)據(jù)標(biāo)注程序。

首先,我們來(lái)構(gòu)建一個(gè)圖形界面。這個(gè)圖形界面里面包含了一個(gè)圖像展示控件、一個(gè)文本輸入控件、四個(gè)按鈕控件。基于此,我們選擇三個(gè)布局來(lái)排列圖形界面的布局。圖形界面窗口中的核心控件是一個(gè)QWidget(),其布局層設(shè)置為網(wǎng)格布局QGridLayout()。在其中放置三個(gè)控件:圖像展示控件QWidget()、文本輸入控件QLineText()、四個(gè)按鈕組QWidget()。

同時(shí),圖像展示控件QWidget()用水平布局層QHBoxLayout()包含一個(gè)QLabel()標(biāo)簽來(lái)占位;按鈕組控件QWidget()用一個(gè)垂直布局層QVBoxLayout()將4個(gè)按鈕控件QPushButton()添加進(jìn)去。最后,代碼如下所示:

class ImgTag(QtWidgets.QMainWindow):
 def __init__(self):
 super().__init__()
 self.setWindowTitle("驗(yàn)證碼圖片標(biāo)注 州的先生 zmister.com")
 # 主控件和主控件布局
 self.main_widget = QtWidgets.QWidget()
 self.main_layout = QtWidgets.QGridLayout()
 self.main_widget.setLayout(self.main_layout)

 # 圖像展示控件
 self.img_widget = QtWidgets.QWidget()
 self.img_layout = QtWidgets.QHBoxLayout()
 self.img_widget.setLayout(self.img_layout)
 # 標(biāo)簽占位
 self.img_view = QtWidgets.QLabel("請(qǐng)選擇一個(gè)文件夾!")
 self.img_view.setAlignment(QtCore.Qt.AlignCenter)
 self.img_layout.addWidget(self.img_view)

 # 圖像標(biāo)注控件
 self.img_input = QtWidgets.QLineEdit()

 # 控制按鈕控件
 self.opera_widget = QtWidgets.QWidget()
 self.opera_layout = QtWidgets.QVBoxLayout()
 self.opera_widget.setLayout(self.opera_layout)
 # 各個(gè)按鈕
 self.select_img_btn = QtWidgets.QPushButton("選擇目錄")
 self.previous_img_btn = QtWidgets.QPushButton("上一張")
 self.previous_img_btn.setEnabled(False)
 self.next_img_btn = QtWidgets.QPushButton("下一張")
 self.next_img_btn.setEnabled(False)
 self.save_img_btn = QtWidgets.QPushButton("保存")
 self.save_img_btn.setEnabled(False)
 # 添加按鈕到布局
 self.opera_layout.addWidget(self.select_img_btn)
 self.opera_layout.addWidget(self.previous_img_btn)
 self.opera_layout.addWidget(self.next_img_btn)
 self.opera_layout.addWidget(self.save_img_btn)

 # 將控件添加到主控件布局層
 self.main_layout.addWidget(self.img_widget,0,0,4,4)
 self.main_layout.addWidget(self.opera_widget,0,4,5,1)
 self.main_layout.addWidget(self.img_input,4,0,1,4)

 # 狀態(tài)欄
 self.img_total_current_label = QtWidgets.QLabel()
 self.img_total_label = QtWidgets.QLabel()
 self.statusBar().addPermanentWidget(self.img_total_current_label)
 self.statusBar().addPermanentWidget(self.img_total_label, stretch=0) # 在狀態(tài)欄添加永久控件

 # 設(shè)置UI界面核心控件
 self.setCentralWidget(self.main_widget)

運(yùn)行上述代碼,我們可以得到以下如下圖所示的圖形界面:

下面,我們?yōu)檫@個(gè)靜態(tài)的圖形界面添加事件響應(yīng)。

二、選擇目錄讀取文件

首先,我們來(lái)實(shí)現(xiàn)“選擇目錄”按鈕的功能。這個(gè)按鈕點(diǎn)擊之后,需要打開(kāi)文件夾選擇框,然后在選擇一個(gè)文件夾之后,自動(dòng)讀取文件夾內(nèi)的圖片文件,并將第一張圖片顯示到圖形展示控件上。

在這里,我們通過(guò)QFileDialog.getExistingDirectory()來(lái)實(shí)現(xiàn)調(diào)用文件夾對(duì)話框,其會(huì)返回所選擇文件夾路徑的字符串。然后通過(guò)os模塊的listdir()方法,獲取文件夾下所有的文件,對(duì)其進(jìn)行遍歷,提取出圖片文件,將這些圖片文件添加到一個(gè)新的列表中。代碼如下所示:

# 選擇目錄按鈕
def select_img_click(self):
 self.dir_path = QtWidgets.QFileDialog.getExistingDirectory(self,'選擇文件夾')
 # print(self.dir_path)
 dir_list = os.listdir(self.dir_path)
 img_list = []
 for dir in dir_list:
 suffix_list = ['jpg','png','jpeg','bmp',]
 if dir.split('.')[-1].lower() in suffix_list:
  img_list.append(dir)

接著,我們繼續(xù)遍歷這個(gè)列表,生成一個(gè)圖片的索引字典,用于記錄每個(gè)圖片的順序信息,方便進(jìn)行上一張、下一張按鈕的切換操作。

# 圖像文件索引字典
self.img_index_dict = dict()
for i,d in enumerate(img_list):
 self.img_index_dict[i] = d
self.current_index = 0 # 當(dāng)前的圖像索引
# 當(dāng)前圖片文件路徑
self.current_filename = os.path.join(
 self.dir_path,self.img_index_dict[self.current_index]
)

然后,借助QImage()類實(shí)例化一個(gè)Qt的圖像,在圖像占位標(biāo)簽中通過(guò)setPixmap設(shè)置顯示圖像。

# 實(shí)例化一個(gè)圖像
image = QtGui.QImage(self.current_filename)
self.img_width = image.width() # 圖片寬度
self.img_height = image.height() # 圖片高度
self.img_scale = 1
self.image = image.scaled(self.img_width*self.img_scale,self.img_height*self.img_scale)

# 在img_view控件中顯示圖像
self.img_view.setPixmap(QtGui.QPixmap.fromImage(self.image))

接著再設(shè)置文本輸入框的內(nèi)容、獲取文本輸入框的焦點(diǎn)并全選文本輸入框的內(nèi)容:

# 設(shè)置img_input控件文本內(nèi)容
self.img_input.setText(self.current_text)
self.img_input.setFocus() # 獲取輸入框焦點(diǎn)
self.img_input.selectAll() # 全選文本

最后在狀態(tài)欄設(shè)置圖片數(shù)量的信息,包括當(dāng)前圖片和圖片總數(shù):

# 設(shè)置狀態(tài)欄 圖片數(shù)量信息
self.img_total_current_label.setText("{}".format(self.current_index+1))
self.img_total_label.setText("/{total}".format(total=len(img_list)))

以上這些代碼都是寫在select_img_click()方法操作。在完成select_img_click()這個(gè)方法的編寫后,我們將其綁定到“選擇目錄”的點(diǎn)擊信號(hào)上:

self.select_img_btn.clicked.connect(self.select_img_click)

這樣,就實(shí)現(xiàn)了選擇目錄,并顯示目錄中的第一張圖片的功能。效果如下動(dòng)圖所示:

下面,我們?cè)賮?lái)實(shí)現(xiàn)下一張圖片的按鈕功能

三、切換下一張圖片

要切換下一張圖片,我們首先需要將當(dāng)前顯示的圖片重命名為文本輸入框中的內(nèi)容:

# 下一張圖片
def next_img_click(self):
 # 修改當(dāng)前圖像文件名
 new_tag = self.img_input.text() # 獲取當(dāng)前輸入框內(nèi)容
 current_img = self.img_index_dict[self.current_index] # 獲取當(dāng)前圖片名稱
 try:
 os.rename(
  os.path.join(self.dir_path,current_img),
  os.path.join(self.dir_path,new_tag+'.'+current_img.split('.')[-1])
 ) # 修改文件名
 self.img_index_dict[self.current_index] = new_tag+'.'+current_img.split('.')[-1]
 except FileExistsError as e: # 同名文件異常
 print(repr(e))
 QtWidgets.QMessageBox.information(
  self, '提示', '已存在同名文件!',
  QtWidgets.QMessageBox.Ok
 )

接下來(lái),將圖片當(dāng)前索引變量值加1,通過(guò)這個(gè)索引值獲取到下一張圖片的文件名,再按照之前的方式將其讀取為圖像并顯示在標(biāo)簽占位控件上,同時(shí)更新?tīng)顟B(tài)欄的信息:

# 當(dāng)前圖像索引加1
self.current_index += 1
if self.current_index in self.img_index_dict.keys():
 # 當(dāng)前圖片文件路徑
 self.current_filename = os.path.join(
 self.dir_path, self.img_index_dict[self.current_index]
 )
 # 實(shí)例化一個(gè)圖像
 image = QtGui.QImage(self.current_filename)
 self.img_width = image.width() # 圖片寬度
 self.img_height = image.height() # 圖片高度
 self.img_scale = 1
 self.image = image.scaled(self.img_width * self.img_scale, self.img_height * self.img_scale)

 # 在img_view控件中顯示圖像
 self.img_view.setPixmap(QtGui.QPixmap.fromImage(self.image))
 # 當(dāng)前文件名
 self.current_text = self.img_index_dict[self.current_index].split('.')[0]
 # 設(shè)置img_input控件文本內(nèi)容
 self.img_input.setText(self.current_text)
 self.img_input.setFocus() # 獲取輸入框焦點(diǎn)
 self.img_input.selectAll() # 全選文本

 # 設(shè)置狀態(tài)欄
 self.img_total_current_label.setText(str(self.current_index+1))
else:
 self.current_index -=1
 QtWidgets.QMessageBox.information(
 self,'提示','所有圖片已標(biāo)注完!',
 QtWidgets.QMessageBox.Ok
 )

這樣,調(diào)用next_img_click()方法,我們就可以切換下一張圖片。我們將其綁定在“下一張”按鈕、“保存”按鈕和文本輸入框的回車信號(hào)上,就可以實(shí)現(xiàn)點(diǎn)擊“下一張”按鈕、“保存”按鈕或是在標(biāo)注完一個(gè)數(shù)據(jù)后直接回車就能切換到下一張圖片:

self.next_img_btn.clicked.connect(self.next_img_click)
self.save_img_btn.clicked.connect(self.next_img_click)
self.img_input.returnPressed.connect(self.next_img_click) # 回車事件綁定

這樣,切換下一張圖片的功能也實(shí)現(xiàn)了,其效果如下動(dòng)圖所示:

四、切換上一張圖片

有時(shí)候我們需要返回前面標(biāo)注的圖片,這時(shí)候切換上一張圖片的功能也是很有必要的。切換上一張圖片的邏輯與切換下一張圖片的邏輯基本一致,只是需要將圖像的索引值減1:

# 上一張圖片
def previous_img_click(self):
 # 修改當(dāng)前圖像文件名
 new_tag = self.img_input.text() # 獲取當(dāng)前輸入框內(nèi)容
 current_img = self.img_index_dict[self.current_index] # 獲取當(dāng)前圖片名稱
 try:
 os.rename(
  os.path.join(self.dir_path, current_img),
  os.path.join(self.dir_path, new_tag + '.' + current_img.split('.')[-1])
 ) # 修改文件名
 self.img_index_dict[self.current_index] = new_tag + '.' + current_img.split('.')[-1]
 except FileExistsError as e: # 同名文件異常
 print(repr(e))
 QtWidgets.QMessageBox.information(
  self, '提示', '已存在同名文件!',
  QtWidgets.QMessageBox.Ok
 )

 # 當(dāng)前圖像索引加1
 self.current_index -= 1
 if self.current_index in self.img_index_dict.keys():
 # 當(dāng)前圖片文件路徑
 self.current_filename = os.path.join(
  self.dir_path, self.img_index_dict[self.current_index]
 )
 # 實(shí)例化一個(gè)圖像
 image = QtGui.QImage(self.current_filename)
 self.img_width = image.width() # 圖片寬度
 self.img_height = image.height() # 圖片高度
 self.img_scale = 1
 self.image = image.scaled(self.img_width * self.img_scale, self.img_height * self.img_scale)

 # 在img_view控件中顯示圖像
 self.img_view.setPixmap(QtGui.QPixmap.fromImage(self.image))
 # 當(dāng)前文件名
 self.current_text = self.img_index_dict[self.current_index].split('.')[0]
 # 設(shè)置img_input控件文本內(nèi)容
 self.img_input.setText(self.current_text)
 self.img_input.setFocus() # 獲取輸入框焦點(diǎn)
 self.img_input.selectAll() # 全選文本

 # 設(shè)置狀態(tài)欄
 self.img_total_current_label.setText(str(self.current_index + 1))
 else:
 self.current_index += 1
 QtWidgets.QMessageBox.information(
  self, '提示', '圖片列表到頂了!',
  QtWidgets.QMessageBox.Ok
 )

可以看到,這和切換下一張圖片的代碼幾乎是一致的,因?yàn)槠浜诵倪壿嫳緛?lái)就是一樣的,我們將“上一張”按鈕的點(diǎn)擊信號(hào)綁定在這個(gè)方法上,就可以實(shí)現(xiàn)切換上一張圖片的功能了:

self.previous_img_btn.clicked.connect(self.previous_img_click)

其效果如下動(dòng)圖所示:

五、圖片縮放

到這里,我們的驗(yàn)證碼圖片數(shù)據(jù)標(biāo)注程序基本上已經(jīng)完成了,但是突然發(fā)現(xiàn),有些驗(yàn)證碼圖片很變態(tài),它的干擾線和干擾點(diǎn)簡(jiǎn)直讓人無(wú)法看清它到底是什么字符,這樣的情況下可能需要把圖片放大或縮小一點(diǎn),方便我們確認(rèn)驗(yàn)證碼圖片上的信息,所以,我們的程序還需要一個(gè)圖片縮放功能。最終,我們實(shí)現(xiàn)的效果是,按住Ctrl+鼠標(biāo)滾輪,滾輪向上,圖片放大,滾輪向下,圖片縮小。這是通過(guò)重寫鼠標(biāo)滾輪事件來(lái)實(shí)現(xiàn)的:

# 重寫鼠標(biāo)滾輪事件
def wheelEvent(self, event):
 # 如果按住了Ctrl
 if event.modifiers() == QtCore.Qt.ControlModifier:
 try:
  delta = event.angleDelta().y()
  if delta > 0:
  self.img_scale += 0.25
  self.image_scaled = self.image.scaled(self.img_width * self.img_scale, self.img_height * self.img_scale)
  self.img_view.setPixmap(QtGui.QPixmap.fromImage(self.image_scaled))
  self.statusBar().showMessage("當(dāng)前圖片縮放比例為:{}%".format(self.img_scale * 100))
  elif delta < 0:
  if self.img_scale > 0.25:
   self.img_scale -= 0.25
   self.image_scaled = self.image.scaled(self.img_width * self.img_scale, self.img_height * self.img_scale)
   self.img_view.setPixmap(QtGui.QPixmap.fromImage(self.image_scaled))
   self.statusBar().showMessage("當(dāng)前圖片縮放比例為:{}%".format(self.img_scale * 100))
 except Exception as e:
  print(traceback.print_exc())
  print(repr(e))

最后,這樣圖片縮放的功能也實(shí)現(xiàn)了,其效果如下所示:

六、程序完整代碼

以上,我們的圖片驗(yàn)證碼數(shù)據(jù)標(biāo)注程序就完全編寫好了,基于此,我們可以進(jìn)一步使用Pyinstaller等打包工具,將其打包為二進(jìn)制的可執(zhí)行文件,方便傳播使用。

源碼下載地址:鏈接: https://pan.baidu.com/s/1FadzPC2FoIJNPMCmpYBKRg 提取碼: e4w4

總結(jié)

以上所述是小編給大家介紹的Python編寫一個(gè)驗(yàn)證碼圖片數(shù)據(jù)標(biāo)注GUI程序附源碼,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
如果你覺(jué)得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!

相關(guān)文章

  • 關(guān)于django 1.10 CSRF驗(yàn)證失敗的解決方法

    關(guān)于django 1.10 CSRF驗(yàn)證失敗的解決方法

    今天小編就為大家分享一篇關(guān)于django 1.10 CSRF驗(yàn)證失敗的解決方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-08-08
  • Python中的with語(yǔ)句與上下文管理器學(xué)習(xí)總結(jié)

    Python中的with語(yǔ)句與上下文管理器學(xué)習(xí)總結(jié)

    在Python中作為上下文管理器的對(duì)象可以使用with語(yǔ)句,提供上下文管理器的contextlib模塊的使用則是Python編程中的高級(jí)技巧,下面我們就來(lái)詳細(xì)整理一下Python中的with語(yǔ)句與上下文管理器學(xué)習(xí)總結(jié):
    2016-06-06
  • Python實(shí)現(xiàn)處理逆波蘭表達(dá)式示例

    Python實(shí)現(xiàn)處理逆波蘭表達(dá)式示例

    這篇文章主要介紹了Python實(shí)現(xiàn)處理逆波蘭表達(dá)式操作,結(jié)合實(shí)例形式分析了逆波蘭表達(dá)式的概念、原理及Python針對(duì)逆波蘭表達(dá)式的定義與計(jì)算相關(guān)操作技巧,需要的朋友可以參考下
    2018-07-07
  • Python實(shí)現(xiàn)帶百分比的進(jìn)度條

    Python實(shí)現(xiàn)帶百分比的進(jìn)度條

    本文給大家匯總介紹了3種使用Python實(shí)現(xiàn)帶百分比進(jìn)度條的代碼,非常的簡(jiǎn)單實(shí)用,有需要的小伙伴可以參考下
    2016-06-06
  • python socket模塊創(chuàng)建和使用套接字示例詳解

    python socket模塊創(chuàng)建和使用套接字示例詳解

    這篇文章主要為大家介紹了python socket模塊來(lái)創(chuàng)建和使用套接字示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-06-06
  • 如何在Flask中實(shí)現(xiàn)數(shù)據(jù)分組流程詳解

    如何在Flask中實(shí)現(xiàn)數(shù)據(jù)分組流程詳解

    在Flask中,數(shù)據(jù)分組是指將一組數(shù)據(jù)按照某種方式進(jìn)行分類,以便更好地對(duì)數(shù)據(jù)進(jìn)行處理和展示,可以使用Python內(nèi)置的itertools模塊中的groupby方法,或者使用SQL語(yǔ)句中的GROUP?BY子句來(lái)實(shí)現(xiàn)數(shù)據(jù)分組,這篇文章介紹了在Flask中實(shí)現(xiàn)數(shù)據(jù)分組,感興趣的同學(xué)可以參考下文
    2023-05-05
  • windows環(huán)境下tensorflow安裝過(guò)程詳解

    windows環(huán)境下tensorflow安裝過(guò)程詳解

    這篇文章主要為大家詳細(xì)介紹了windows環(huán)境下tensorflow安裝過(guò)程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-03-03
  • Python使用folium excel繪制point

    Python使用folium excel繪制point

    今天小編就為大家分享一篇關(guān)于Python使用folium excel繪制point,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-01-01
  • 一文帶你理解Python中面向?qū)ο缶幊蘋OP的概念

    一文帶你理解Python中面向?qū)ο缶幊蘋OP的概念

    在Python中,面向?qū)ο缶幊蹋∣OP)是一種在編程中使用對(duì)象和類的編程范式,它旨在實(shí)現(xiàn)現(xiàn)實(shí)世界的實(shí)體,下面我們就一起來(lái)看看它的相關(guān)知識(shí)吧
    2023-08-08
  • python使用socket進(jìn)行簡(jiǎn)單網(wǎng)絡(luò)連接的方法

    python使用socket進(jìn)行簡(jiǎn)單網(wǎng)絡(luò)連接的方法

    這篇文章主要介紹了python使用socket進(jìn)行簡(jiǎn)單網(wǎng)絡(luò)連接的方法,實(shí)例分析了Python使用socket的基本技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2015-04-04

最新評(píng)論