LoginSignup
0
1

More than 3 years have passed since last update.

イラストを解析(めも)

Posted at
test.py

import cv2
import glob
import os
import numpy as np


def ToneExtract(path_input,path_output):
    img = cv2.imread(path_input)
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

    #https://design-spice.com/2012/07/09/photoshop-color-sheme/
    #https://www.google.com/url?sa=i&url=http%3A%2F%2Fxn--rms9i4ix79n.jp.net%2F%25E5%25A4%2596%25E5%25A3%2581%25E5%25A1%2597%25E8%25A3%2585%25E3%2581%25AE%25E5%25BD%25A9%25E3%2582%258A%25E3%2582%25B3%25E3%2583%25A9%25E3%2583%25A0%2F%25E3%2583%2588%25E3%2583%25BC%25E3%2583%25B3%25E3%2581%25AB%25E5%259F%25BA%25E3%2581%25A5%25E3%2581%2584%25E3%2581%259F%25E9%2585%258D%25E8%2589%25B2%25E6%2596%25B9%25E6%25B3%2595%25E3%2580%2581%25E9%25A1%259E%25E4%25BC%25BC%25E3%2583%2588%25E3%2583%25BC%25E3%2583%25B3%25E9%2585%258D%25E8%2589%25B2%2F&psig=AOvVaw0UClXlbAjJqXYI4tm9esR2&ust=1610260671526000&source=images&cd=vfe&ved=0CA0QjhxqFwoTCPic_cueju4CFQAAAAAdAAAAABAE
    #彩度ごとの4グループ 0-100
    arr_Saido_High = list(range(90,100))
    arr_Saido_Middle= list(range(70,90))
    arr_Saido_Low = list(range(40,70))
    arr_Saido_Buttom = list(range(0,40))

    # 白いHSVデータ作成
    white = np.array([0,0,255],dtype="uint8")
    white_color = np.tile(white, (hsv.shape[0],hsv.shape[1],1))
    white_color.reshape(hsv.shape)

    # 各トーン
    list_tone = []
    list_tone.append({"S": arr_Saido_High, "V": list(range(10, 95)), "Name": "vivid", "cnt": 0, "data": white_color.copy()})
    list_tone.append({"S": arr_Saido_Middle, "V": list(range(60, 95)), "Name": "blight", "cnt": 0, "data": white_color.copy()})
    list_tone.append({"S": arr_Saido_Middle, "V": list(range(40, 60)), "Name": "strong", "cnt": 0, "data": white_color.copy()})
    list_tone.append({"S": arr_Saido_Middle, "V": list(range(30, 40)), "Name": "deep", "cnt": 0, "data": white_color.copy()})
    list_tone.append({"S": arr_Saido_Low, "V": list(range(70, 100)), "Name": "light", "cnt": 0, "data": white_color.copy()})
    list_tone.append({"S": arr_Saido_Low, "V": list(range(60, 70)), "Name": "soft", "cnt": 0, "data": white_color.copy()})
    list_tone.append({"S": arr_Saido_Low, "V": list(range(40, 60)), "Name": "dull", "cnt": 0, "data": white_color.copy()})
    list_tone.append({"S": arr_Saido_Low, "V": list(range(20, 40)), "Name": "dark", "cnt": 0, "data": white_color.copy()})
    list_tone.append({"S": arr_Saido_Buttom, "V": list(range(80, 100)), "Name": "pale", "cnt": 0, "data": white_color.copy()})
    list_tone.append({"S": arr_Saido_Buttom, "V": list(range(60, 80)), "Name": "light_grayish", "cnt": 0,"data": white_color.copy()})
    list_tone.append({"S": arr_Saido_Buttom, "V": list(range(40, 60)), "Name": "grayish", "cnt": 0, "data": white_color.copy()})
    list_tone.append({"S": arr_Saido_Buttom, "V": list(range(20, 40)), "Name": "dark_grayish", "cnt": 0,"data": white_color.copy()})

    cnt_no_tone = 0
    none_data = white_color.copy()

    # トーンごとにピクセルを分類
    arr = hsv[:, :, (1)]
    for height in range(arr.shape[0]):
        for width in range(arr.shape[1]):
            Saido = hsv[:, :, (1)][height][width]
            Value = hsv[:, :, (2)][height][width]
            if Saido == 0:
                none_data[height][width] =hsv[height][width]
                cnt_no_tone = cnt_no_tone + 1
                continue
            #https://axa.biopapyrus.jp/ia/color-space/opencv-hsv.html
            #opencvだと彩度明度ともに0-255。0-100の範囲に変換する。
            Saido = int(100 * Saido/255)
            Value = int(100 * Value/255)
            notExistflg = False
            for idx in range(len(list_tone)):
                if Saido in list_tone[idx]["S"]:
                    if Value in list_tone[idx]["V"]:
                        #該当のピクセル抽出
                        list_tone[idx]["data"][height][width] =hsv[height][width]
                        notExistflg = True
                        break
            if notExistflg == False:
                cnt_no_tone = cnt_no_tone + 1
                none_data[height][width] =hsv[height][width]


    # 色空間変換
    for idx in range(len(list_tone)):
        img_gs = cv2.cvtColor(list_tone[idx]["data"], cv2.COLOR_HSV2BGR)
        list_tone[idx]["img"] = img_gs

    # 抽出回数カウント
    for idx in range(len(list_tone)):
        img = list_tone[idx]["img"]
        img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        list_tone[idx]["cnt"] = np.sum(img_gray != 255)

    #抽出順でソート
    change = True
    while change:
        change = False
        for i in range(len(list_tone) - 1):
            if list_tone[i]["cnt"] < list_tone[i + 1]["cnt"]:
                list_tone[i], list_tone[i + 1] = list_tone[i + 1], list_tone[i]
                change = True

    #保存
    allpixel = arr.shape[0]*arr.shape[1] - cnt_no_tone
    cnt = 0
    for tone in list_tone:
        cnt+=1
        # 上位5個のみ出力
        if cnt >= 5:
            break
        print(tone["Name"],tone["cnt"])
        ratio = str(int(100*(tone["cnt"]/allpixel)).zfill(2)) + "%"
        cv2.imwrite(path_output + ratio + "_" + tone["Name"] + ".png", tone["img"], [int(cv2.IMWRITE_JPEG_QUALITY), 0])

    # 分類されないデータ
    # img_gs = cv2.cvtColor(none_data, cv2.COLOR_HSV2BGR)
    # cv2.imwrite(path_output + "NonCategory.png", img_gs, [int(cv2.IMWRITE_JPEG_QUALITY), 0])

    return


def Grayscale(path_input,path_output):
    img = cv2.imread(path_input)
    img_gs = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    cv2.imwrite(path_output + ".png", img_gs, [int(cv2.IMWRITE_JPEG_QUALITY), 0])
    return

def SaidoGrayscale(path_input,path_output):
    img = cv2.imread(path_input)

    # 彩度のグレースケール化
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    hsv[:, :, (2)] = hsv[:, :, (1)]

    img_gs = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)
    img_gs = cv2.cvtColor(img_gs, cv2.COLOR_BGR2GRAY)
    cv2.imwrite(path_output + ".png", img_gs, [int(cv2.IMWRITE_JPEG_QUALITY), 0])
    return


def SaidoExtarct(path_input, path_output):
    img = cv2.imread(path_input)

    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    arr = hsv[:, :, (1)]
    for height in range(arr.shape[0]):
        for width in range(arr.shape[1]):
            saido = arr[height][width]
            if saido < 10:
                #彩度ゼロはスキップ
                continue
            # 0(red) - 100(blue) で正規化
            blue_saido = 100
            norm_saido = int(abs(blue_saido -blue_saido * saido/255))
            hsv[:, :, (0)][height][width] = norm_saido
            hsv[:, :, (1)][height][width] = 255
            hsv[:, :, (2)][height][width] = 255

    img_gs = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)
    cv2.imwrite(path_output + ".png", img_gs, [int(cv2.IMWRITE_JPEG_QUALITY), 0])
    return


def SimpleHue(path_input,path_output):
    img = cv2.imread(path_input)

    # 色相の単純化
    cnt = 0
    h_max = 360
    h_sep = 10
    h_unit = h_max / h_sep
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    arr = hsv[:, :, (0)]
    for height in range(arr.shape[0]):
        for width in range(arr.shape[1]):
            if 240 < hsv[:, :, (2)][height][width]:
                # 白色はスキップ
                continue
            cnt += 1
            hue = arr[height][width]
            group = hue // h_unit
            output = group * h_sep
            # hsv[:, :, (0)][height][width] = output
            hsv[:, :, (1)][height][width] = 100
            hsv[:, :, (2)][height][width] = 255

    img_gs = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)
    cv2.imwrite(path_output + ".png", img_gs, [int(cv2.IMWRITE_JPEG_QUALITY), 0])
    return

if __name__ == '__main__':
    output_path = 'output/'
    try:
        os.makedirs(output_path)
    except FileExistsError:
        pass

    imglist = []
    files = glob.glob("*.png")
    for file in files:
        imglist.append(file)
    files = glob.glob("*.jpg")
    for file in files:
        imglist.append(file)
    files = glob.glob("*.jpeg")
    for file in files:
        imglist.append(file)

    for fileNm in imglist:
        # イラストをトーンごとに分類
        ToneExtract(fileNm, output_path + fileNm + '_tone')

        # グレースケール
        Grayscale(fileNm, output_path + fileNm + '_grayscale')

        # 彩度の強さを抽出(赤->緑->青の順で弱い)
        SaidoExtarct(fileNm, output_path + fileNm + '_saido_extract')

        # 360パターンある色相を単純化
        SimpleHue(fileNm, output_path + fileNm + '_saido_gray')

        SaidoGrayscale(fileNm, output_path + fileNm + '_shikiso_simple')



0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1