用wxPython编写图像情感标注工具并编译成exe文件

本文介绍了一款使用wxPython开发的情感标注工具,用于为图像打上情感标签(VA值),支持PNG格式图像批量处理,并能将标注结果保存至CSV文件。文章提供了完整的Python源代码及如何在虚拟环境中编译成exe文件的方法。

用wxPython编写图像情感标注工具并编译成exe文件

该标注工具可以选择执行Python文件,也可以选择双击编译好的exe文件,还可以修改Python文件,新建虚拟环境并重新编译exe文件。

界面如下:
标注工具界面

1.Python代码

  • 新建虚拟环境,安装wxPython、pandas。
  • 把Python文件放到与“图片xxx”文件夹同目录的地方,代码会读取文件夹中的PNG图片,并在与Python文件同目录的地方生成VA.csv文件。
  • cmd窗口中进入该目录,执行python biaozhu.py
import wx
import os
import pandas as pd
import random

IMG_EXTENSIONS = [
    # '.jpg', '.JPG', '.jpeg', '.JPEG',
    # '.png', '.PNG', '.ppm', '.PPM', '.bmp', '.BMP',
    '.png', '.PNG' # 下面加载图像部分只设置了PNG格式
]
def is_image_file(filename):
    return any(filename.endswith(extension) for extension in IMG_EXTENSIONS)
def make_dataset(dir, max_dataset_size=float("inf")):
    images = []
    assert os.path.isdir(dir), '%s is not a valid directory' % dir
    for root, _, fnames in sorted(os.walk(dir)):
        for fname in fnames:
            if is_image_file(fname):
                # path = os.path.join(root, fname)
                images.append(fname) # 101.png
    return images[:min(max_dataset_size, len(images))]

def GetImageList(path='.'):
    dirs = []
    for root, dirs, files in os.walk(path):
        dirs = dirs # 一次循环,只要当前目录的子目录
        break
    if dirs == []:
        return None
    else:
        for dir1 in dirs:
            if '图片' in dir1:
                dir1 = os.path.join(path, dir1)
                image_list = make_dataset(dir1)
                return dir1, image_list
        return None

def GetCsv(file_name = 'VA.csv'): # 读取VA.csv文件,获取图像名称列表
    HEADER=['name','v','a']
    if os.path.exists(file_name):
        data = pd.read_csv(file_name, skiprows=1, names=HEADER)
        image_list = data['name'].tolist()
        v_list = data['v'].tolist()
        a_list = data['a'].tolist()
        dir, _ = GetImageList()
        return dir,image_list,v_list,a_list
    else:
        dir, image_list = GetImageList()
        random.shuffle(image_list)
        v_list = [1.0]*len(image_list)
        a_list = [1.0]*len(image_list)
        dataframe = pd.DataFrame({'name':image_list,'v':v_list, 'a':a_list})
        dataframe.to_csv(file_name,index=False,sep=',')
        return dir,image_list,v_list,a_list


class Demo(wx.Frame): 
    def __init__(self):
        wx.Frame.__init__(self,None,wx.ID_ANY,"标注VA值",size =(600, 650))
        
        self.dir, self.image_list, self.v_list, self.a_list = GetCsv()
        self.index = 0
        self.length = len(self.image_list)
        print(self.dir)

        panel = wx.Panel(self, -1)
        ##############################################################
        multiStr ="选择VA值后点击下一张。\nVA.csv文件在同一目录下。\n每次启动都会重覆盖原数据。\n但只有结束或按写入文件才会把数据写入文件。"
        text1 = wx.StaticText(panel,
                              wx.ID_ANY,
                              multiStr,
                              (10, 10))
                              
        file_name = os.path.join(self.dir, self.image_list[self.index]) # 第一张图像的地址
        image = wx.Image(file_name, wx.BITMAP_TYPE_PNG) # 读取PNG图像
        temp = image.ConvertToBitmap()                           
        size = temp.GetWidth(), temp.GetHeight()                
        self.bmp = wx.StaticBitmap(panel, -1, temp, pos=(0, 90),size=size)

        self.button1 = wx.Button(panel, -1, u"下一张", pos=(400, 50))
        self.Bind(wx.EVT_BUTTON, self.OnClick1, self.button1)
        self.button1.SetDefault()
        self.button2 = wx.Button(panel, -1, u"写入文件", pos=(500, 50))
        self.Bind(wx.EVT_BUTTON, self.OnClick2, self.button2)
        self.button2.SetDefault()

        sampleList1 = ['1', '2', '3', '4', '5', '6', '7', '8', '9']
        self.radiobox1 = wx.RadioBox(panel, -1, "V=1是非常消极,V=9是非常积极", (10, 500), wx.DefaultSize,
                        sampleList1, 9, wx.RA_SPECIFY_COLS)
        sampleList2 = ['1', '2', '3', '4', '5', '6', '7', '8', '9']
        self.radiobox2 = wx.RadioBox(panel, -1, "A=1是非常平静,A=9是非常兴奋", (10, 550), wx.DefaultSize,
                        sampleList2, 9, wx.RA_SPECIFY_COLS)

    def GetRadioData(self):
        v = int(self.radiobox1.GetStringSelection()) # 获得被选择的符号并转成整数
        self.v_list[self.index] = v
        a = int(self.radiobox2.GetStringSelection())
        self.a_list[self.index] = a

    def SaveData(self,file_name = 'VA.csv'):
        dataframe = pd.DataFrame({'name':self.image_list,'v':self.v_list, 'a':self.a_list})
        dataframe.to_csv(file_name,index=False,sep=',')

    def OnClick1(self, event):
        # print("本次选择了%s,index=%d" %(self.radiobox.GetStringSelection(), self.radiobox.GetSelection()))
        if self.index == self.length - 1:
            self.GetRadioData()
            self.SaveData()
            self.Close(True) # 关闭窗口
        else:
            self.GetRadioData()
            self.index = self.index + 1
            file_name = os.path.join(self.dir, self.image_list[self.index])
            image = wx.Image(file_name, wx.BITMAP_TYPE_PNG)
            temp = image.ConvertToBitmap()
            self.bmp.SetBitmap(temp) # 更新展示的图像
    def OnClick2(self,event):
        self.GetRadioData()
        self.SaveData()
        # print('get and save data')


if __name__ == '__main__':

    # image_list = GetImageList()
    app = wx.App()
    frame = Demo()
    frame.Show(True)
    app.MainLoop()

2.在虚拟环境中编译成exe文件

  • 打包的时候如果没有新建虚拟环境,很多无关的库也会被打包进去,结果exe文件就会很大,达到327M,双击以后1分钟才能出现图像界面。新建虚拟环境再打包就只剩33M。exe文件放在与Python文件同目录的地方,双击一下就行。
  • 打包:
    新建虚拟环境,conda和pipenv都可以(如果前一步是在虚拟环境中执行Python代码那就不需要再新建)。conda info --env查看已有虚拟环境,conda create --name wx python=3.6创建名为wx的虚拟环境,activate wx和deactivate wx分别是win10启动和退出虚拟环境, conda[pip] install wxPython pandas pyinstaller安装需要的库,conda list查看已安装的库,conda remove -n wx --all删除虚拟环境。
    确认代码可以执行以后,用pyinstaller打包成exe文件,pyinstaller -F biaozhu.py
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值