python--鼠标给正样本图片作框图标记,保存坐标

      在做目标检测的时候,需要从拍下来的图片中截取我们的目标,将目标的坐标保存在文档中,方便做训练的时候直接读取图片,截取特定roi区域即可作为正样本投入训练了。

     下面是我用python写的一个简单的脚本。

     两个函数,一个是鼠标的回调函数,一个是主函数。

     回调函数调用全局变量保存矩形框的坐标xmin ymin xmax ymax  还有就是逻辑flag,和图片img; 

    首先读取图片,显示图片,创建txt文档(坐标写入该文档),当鼠标在图片上按下左键时,触发回调函数的第一个event,表示进入拖动flag , 因为框图的时候我们是要拖动鼠标的,当鼠标一直在拖动的时候回调函数一直在第二个event, 创一个临时temimage 变量保存一开始img的图片, 在临时变量图片中绘矩形框,不然你会看到整个框都是一个颜色(可以试一下); 鼠标拖动结束后,进入第三个event, 便确认了矩形框的最终位置。 

    这时候在while循环里就可以绘制矩形框了,在原始的img图片上画;

   当你按下‘q’ 键时表示退出;

   按下‘c’键时表示切换下一张图片,初始化一下imgposition 、重新读取新的img图片即可,图片读完了也退出break;

   按下'r' 时表示该图画错矩形框了,需要重新画,初始化一下imgposition 、img 重新读取没有被绘制过的图片即可。

   最后销毁窗口,关闭文件。

import cv2
import os
import numpy as np

# 创建鼠标事件的回调函数
def OnMouseAction(event,x,y,flags,param):
    global x1, y1, x2, y2, drawflag, img # 调用全局变量

    if event == cv2.EVENT_LBUTTONDOWN and drawflag == 0:
        x1 = x
        y1 = y
        drawflag = 1 # 按下标志位
        
    elif event == cv2.EVENT_MOUSEMOVE and (drawflag == 1 or drawflag == 2) :
        temImage = img.copy() # 为了不保留绘图轨迹
        cv2.rectangle(temImage, (x1, y1), (x, y), (0, 255, 0), 1)
        cv2.imshow('PosImage',temImage)  # 实时显示拖动矩形框
        drawflag = 2 # 拖动标志位
        
    elif event == cv2.EVENT_LBUTTONUP and drawflag == 2:
        x2 = x
        y2 = y
        drawflag = 3 # 按下拖动结束标志位


def main():

    print('[q] : Quit the procedure.\n')
    print('[c] : Change to next picture.\n')
    print('[r] : Restar to draw the rectangle in this picture.\n')
    
    global x1, y1, x2, y2, drawflag, img
    drawflag = 0 # 初始化为0
    
    path = './Picture'
    imgList=os.listdir(path)
    listLen = len(imgList) # 该文件夹图片个数
    listNum = 0
    img = cv2.imread(os.path.join(path, imgList[listNum]), cv2.IMREAD_COLOR)
    restartImg = img.copy() # 重新画的时候用
    imgPosition = '' # 整张图片的坐标
    
    cv2.namedWindow('PosImage')
    cv2.setMouseCallback('PosImage',OnMouseAction)

    txtFile = open('posPicture.txt', 'w')
    txtFile.write(imgList[listNum] + ':') 

    while (True):
        
        if drawflag == 3:
            cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 3) # 画矩形框
            drawflag = 0 # 回归原始标志位
            
            temPosition = '(' +  str(x1) + ',' + str(y1) + ',' + str(x2) + ',' + str(y2) + ')'
            imgPosition = imgPosition + temPosition
            print(imgList[listNum], temPosition)
            
        if drawflag != 2:
            cv2.imshow('PosImage',img)

        
        k=cv2.waitKey(1)
        if k==ord('q'):
            print('Break.')
            break
        
        elif k == ord('c'):
            txtFile.write(imgPosition) # 每切换一张图片将前一张坐标写入
            listNum = listNum + 1
            if listNum >= listLen: # 读取完,跳出
                print('Read over.')
                break
            img = cv2.imread(os.path.join(path, imgList[listNum]), cv2.IMREAD_COLOR) # 读取下一张
            txtFile.write('\n' + imgList[listNum] + ':')
            imgPosition = '' # 换新的图片坐标清空
            print('Change to ', imgList[listNum])
            
        elif k == ord('r'):  # 该图重新画框
            print('Redraw ', imgList[listNum])
            imgPosition = ''
            img = cv2.imread(os.path.join(path, imgList[listNum]), cv2.IMREAD_COLOR) # 清空框

            
    cv2.destroyAllWindows()
    txtFile.close()


if __name__ == '__main__':
    main()

     

  • 0
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值