空中手寫識別之圖像數據處理

每次做圖像數據處理時,都需要重新寫讀取處理文件,保存下以便下次直接複製使用。

#!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")

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章