简易图片打像素标签工具

功能:

制作图片像素点数据集

打开文件夹中的图片,通过鼠标点击图片获取所在鼠标点的像素值,并把打的标签导出为txt。

导入必要的函数库

import math
import os
import cv2 as cv
import numpy as np

定义一些全局变量后面会用到。patchsize表示采集的像素patch大小。

mode = True
testflag = False
idex = 0
patchsize = 9  # 对应像素块大小
# 读取图片
dir = './pic'  # 图片存放的目录

定义读取图片的函数,方便后面循环调用文件夹内的图片。读取后的图片是narray的格式。

def readImage(dir, idex):
    """读取图片"""
    filelist = os.listdir(dir)
    imgname = os.path.join(dir, filelist[idex])
    img1 = cv.imread(imgname)  # 这里必须用cv库里面的imread,否则格式不对会报错
    return img1

定义bgr_patch函数获得像素所处patch的像素平均值

def bgr_patch(img, y, x):
    """输入图片img,输入对应的坐标y,x,输出这个坐标周围一个patch的像素平均值"""
    global patchsize
    n = math.floor(patchsize / 2)
    bgr = img[y - n:y + (n + 1), x - n:x + (n + 1)]  # 选取 5*5=25 的区域
    size = bgr.shape[0]
    sum1 = np.array([0, 0, 0])
    for i in range(size):
        for j in range(size):
            sum1 = sum1 + bgr[i, j]
    ave = sum1 / (size * size)
    ave = np.array([round(ave[0]), round(ave[1]), round(ave[2])])
    print(f"bgr test is {ave}")
    return ave

定义一个窗口函数,作为setMouseCallback的回调函数。在窗口函数中,通过鼠标的不同操作和键盘的操作实现不同的功能。

  • x,y:鼠标所在的位置

# 定义一个窗口
def draw_(event, x, y):
    global idex, dir, mode, data, img1, testflag, patchsize
    n = math.floor(patchsize / 2)
    filelist = os.listdir(dir)
    if event == cv.EVENT_LBUTTONDOWN:
        """左键单击打标签,按e打环境标签,按r打道路标签,按t切换测试集,中间滚动切换图片,按c退出"""
        xy = "%d,%d" % (x, y)
        # bgr = img1[y, x]  # 按照BGR排列,x和y是相反的
        # print(f"bgr origin is {bgr}")
        bgr = bgr_patch(img1, y, x)  # 使用patch
        if mode:
            """道路"""
            rgb = [bgr[2], bgr[1], bgr[0], y, x, 1]  # 转换成RGB排列
            y_size = img1.shape[0]
            x_size = img1.shape[1]
            rgb = [bgr[2] / 255, bgr[1] / 255, bgr[0] / 255,
                   x / x_size, y / y_size, 1]  # 归一化 数值取到0——1之间
            print(f"rgb guiyi is {rgb}")
            cv.circle(img1, (x, y), n, (255, 0, 0), thickness=-1)
            # cv.putText(img1,xy,(x,y),fontFace=cv.FONT_HERSHEY_PLAIN
            # fontScale=2.0,color=(0,0,0),thickness= 1) # 显示标签值
            data.append(rgb)

        else:
            """非道路"""
            rgb = [bgr[2], bgr[1], bgr[0], y, x, 0]  # 转换成RGB排列
            y_size = img1.shape[0]
            x_size = img1.shape[1]
            rgb = [bgr[2] / 255, bgr[1] / 255, bgr[0] / 255, x / x_size,
                   y / y_size, 0]  # 归一化 数值取到0——1之间
            print(f"rgb guiyi is {rgb}")
            cv.circle(img1, (x, y), n, (0, 0, 255), thickness=-1)
            # cv.putText(img1,xy,(x,y),fontFace=cv.FONT_HERSHEY_PLAIN,
            # fontScale=2.0,color=(0,0,0),thickness= 1) # 显示标签值
            data.append(rgb)

    if event == cv.EVENT_MOUSEWHEEL:
        """滚动触发图片切换"""
        if idex != len(filelist) - 2:
            idex = idex + 1
        else:
            idex = 0
        img1 = readImage(dir, idex)

    if event == cv.EVENT_MBUTTONDOWN:
        """单击鼠标中间,存储数据"""
        if testflag:
            file = open('data_test.txt', mode='w+')
            file.writelines(str(data))
            file.close()
        else:
            file = open('data_train.txt', mode='w+')
            file.writelines(str(data))
            file.close()

创建opencv窗口,命名为image,设置鼠标响应函数

cv.namedWindow('image')
cv.setMouseCallback('image', draw_)

主函数写在while循环里面。


# 创建一个列表存储标签和RGB值
data = []
label = []
img1 = readImage(dir, idex)

while 1:
    cv.imshow('image', img1)
    k = cv.waitKey(1) & 0xFF
    if k == ord('r'):
        mode = True
    elif k == ord('e'):
        mode = False
    elif k == ord('t'):
        testflag = ~testflag
        print(f"[testflag] is :{testflag}")
    elif k == ord('c'):
        break
cv.destroyAllWindows()

你可能感兴趣的:(自动驾驶,svm,cv)