代码链接:
功能:
制作图片像素点数据集。
打开文件夹中的图片,通过鼠标点击图片获取所在鼠标点的像素值,并把打的标签导出为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,flag,param):
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()