每次做圖像數據處理時,都需要重新寫讀取處理文件,保存下以便下次直接複製使用。
#!usr/bin/python3
# -*- coding:utf-8 -*-
# author:SingWeek
import os
import cv2
import time
import random
import shutil
import pandas as pd
import numpy as np
import csv
def Read_txt(filename,outfile):
"""
獲取文本中的空中手寫座標點數據
:param filename: 輸入文件名
:param outfile: 保存文件名
:return:
"""
num=0
f=open(filename,'r')
for i in f.readlines():
tmp=i[:-1].split('], [')
framek = np.zeros((300, 300, 3), np.uint8)
lpx,lpy=0,0
for j in range(len(tmp)):
if j==0:
xy=tmp[j][2:].split(', ')
elif j==len(tmp)-1:
xy = tmp[j][:-2].split(', ')
else:
xy = tmp[j].split(', ')
try:
x,y=int(float(xy[0])),int(float(xy[1]))
except:
x,y=0,0
# print(x,y)
if j>=1:
cv2.line(framek, (lpx, lpy), (x, y), (255, 0, 255), 1) # 粉色線爲預測值
lpx,lpy=x,y
cv2.imwrite(outfile+'\\'+'%s.jpg'%num,framek)
num+=1
# outfile="C:\\Users\\singwewk\\Desktop\\202002\\out\\"
# file="C:\\Users\\singwewk\\Desktop\\202002\\細體1.txt"
# for i in os.listdir(file):
# os.makedirs(outfile+i[:-4])
# Read_txt(file,outfile)
def rotate(image, angle, center=None, scale=1.0):
"""
旋轉
:param image: 圖像
:param angle: 角度
:param center: 旋轉中心
:param scale: 倍數
:return:
"""
(h, w) = image.shape[:2]
if center is None:
center = (w // 2, h // 2)
M = cv2.getRotationMatrix2D(center, angle, scale)
rotated = cv2.warpAffine(image, M, (w, h))
return rotated
def moveimg(image, x, y):
"""
圖像偏移
:param image: 圖像
:param x: 偏移座標x
:param y: 偏移座標y
:return:
"""
M = np.float32([[1, 0, x], [0, 1, y]])
shifted = cv2.warpAffine(image, M, (image.shape[1], image.shape[0]))
return shifted
def Img_Formal(filename,outfilename,num=200,imgsize=(128,128)):
"""
圖像隨機變化
:param filename: 載入圖像文件名
:param outfilename: 保存路徑名
:param num: 隨機處理次數
:param imgsize: 圖像大小
:return:
"""
img=cv2.imread(filename)
for i in range(num):
angle=random.randint(-10, 10)
img=rotate(img,angle)#旋轉
x = random.randint(-15,15)
y = random.randint(-20,20)
img=moveimg(img,x,y)
up, down, left, right = random.randint(1,20), random.randint(1,20), random.randint(1,20), random.randint(1,20)
img = cv2.copyMakeBorder(img, up, down, left, right, cv2.BORDER_CONSTANT, value=[0, 0, 0])#通過圖像擴充實現圖像偏移
img = cv2.resize(img, imgsize)#圖像大小歸一化
cv2.imwrite(outfilename+"%s.jpg"%time.time(),img)
def DataFormal(file,outfile,allnum = 200):
"""
空中手寫圖像歸一化處理
:param file: 文件名
:param outfile: 保存文件名
:param allnum: 每種字符圖像的數據量200*1
:return:
"""
os.makedirs(outfile)
for i in os.listdir(file):
print(outfile+i)
try:
os.makedirs(outfile+i)
except:
shutil.rmtree(outfile+i)
os.makedirs(outfile + i)
while allnum>0:
lists=os.listdir(file+i)
random.shuffle(lists)
for j in lists:
filename=file+i+"\\"+j
savefile=outfile+i+"\\"
Img_Formal(filename,savefile,1)
allnum-=1
if allnum==0:
break
def Load_csv(csv_file_name="test.csv"):
"""
從CSV文件中讀取數據信息
:param csv_file_name: CSV文件名
:return: Data:二維數組
"""
csv_reader = csv.reader(open(csv_file_name))
Data=[]
for row in csv_reader:
Data.append(row)
print("Read All!")
return Data
def Write_csv(Data=[[None]],csv_file_name="Train.csv"):
"""
向CSV文件中寫入數據信息,有標籤的話存放在數據最後位
:param csv_file_name: CSV文件名
:return: None,文件夾中會顯示寫入的數據信息
"""
with open(csv_file_name,"a+",newline='') as csvfile:
writer = csv.writer(csvfile)#寫出來存在逗號
# 沒有逗號的寫入方式,但是在讀取的時候需要更改並處理數據
# writer=csv.writer(csvfile, delimiter=' ',quotechar='|', quoting=csv.QUOTE_MINIMAL)
#寫入多行用writerows,寫入單行用writerow
writer.writerows(Data)
print("Write All!")
def Write_Data(filename="..\\imgout\\",csv_file_name="Train.csv",imgsize=(1,128,128)):
#第一層文件夾目錄
Data = []
for file_1 in os.listdir(filename):
#第二層文件夾目錄,第一層文件夾下的下一層文件夾目錄
# print(file_1)file_1爲文件名
filename_1 = os.path.join(filename, file_1)
Data_tmp = []
# print(file_1)
for file_2 in os.listdir(filename_1):
#第三層文件夾,找到對應文件的地址
filename_2 = os.path.join(filename_1, file_2)
Data_tmp1=[]
# print(filename_2)
img = cv2.imread(filename_2,cv2.IMREAD_GRAYSCALE)#二值化的圖像
img=cv2.resize(img,(imgsize[1],imgsize[2]))
ret, img = cv2.threshold(img, 10, 255, cv2.THRESH_BINARY)
w,h=img.shape[:2]
# data=np.reshape(img,[w*h])
for i in range(w):
for j in range(h):
Data_tmp1.append(img[i,j])
#添加標籤
Data_tmp1.append(file_1)
Data_tmp.append(Data_tmp1)
Data=Data+Data_tmp
Write_csv(Data,csv_file_name)
def flat_to_one_hot(labels):
num_classes = np.unique(labels).shape[0]
# print(num_classes)
# print("0",len(num_classes))
num_labels = labels.shape[0]
# print(num_labels)
# print("1",len(num_labels))
index_offset = np.arange(num_labels) * num_classes
# print(index_offset)
# print("2",len(index_offset))
labels_one_hot = np.zeros((num_labels,num_classes))
labels_one_hot.flat[index_offset + labels.ravel()] = 1
return labels_one_hot
def get_data(file,ratio=0.3,imgsize=(1,128,128)):
"""
:param file:文件名
:param validation_size:測試數據
:param imgsize:圖像大小
:return:
"""
data = pd.read_csv(file)
leng=imgsize[1]*imgsize[2]
data=data.sample(frac=1.0)
validation_size=int((len(data)*ratio))
images = data.iloc[:,0:leng].values
labels = data.iloc[:,leng:leng+1].values.ravel()
print("標籤",labels)
# Convert the images from uint8 to double:
images = np.multiply(images,1.0/255.0)
# Convert the labels to one hot encoding:
labels = flat_to_one_hot(labels)
# print("標籤1",labels)
# print(len(labels[1]))
# print(len(images))
# Split the data into validation and training data:
validation_images = images[:validation_size]
validation_labels = labels[:validation_size]
train_images = images[validation_size:]
train_labels = labels[validation_size:]
# Convert the images from flat to matrix form:
train_images = train_images.reshape(train_images.shape[0],imgsize[0],imgsize[1],imgsize[2])
validation_images = validation_images.reshape(validation_images.shape[0],imgsize[0],imgsize[1],imgsize[2])
# Return the data:
return (train_images,train_labels),(validation_images,validation_labels)
"""將空中手寫數據歸一化到固定的數"""
# file="F:\\NewData\\"
# outfile="F:\\OUTNewData\\"
# DataFormal(file,outfile,allnum = 200)
"""將圖像數據轉化成文本數據村房子啊CSV中"""
# Write_Data("F:\\OUTNewData\\","Data.csv")