[PYTHON] Analyze the illustration (Memo)

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 groups by saturation 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))

    #White HSV data creation
    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)

    #Each tone
    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()

    #Classify pixels by tone
    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
            #With opencv, both saturation and brightness are 0-255。0-Convert to a range of 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"]:
                        #Applicable pixel extraction
                        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]


    #Color space transformation
    for idx in range(len(list_tone)):
        img_gs = cv2.cvtColor(list_tone[idx]["data"], cv2.COLOR_HSV2BGR)
        list_tone[idx]["img"] = img_gs

    #Extraction count
    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)

    #Sort by extraction order
    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

    #Save
    allpixel = arr.shape[0]*arr.shape[1] - cnt_no_tone
    cnt = 0
    for tone in list_tone:
        cnt+=1
        #Output only the top 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])

    #Uncategorized data
    # 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)

    #Grayscale saturation
    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:
                #Skip zero saturation
                continue
            # 0(red) - 100(blue)Normalized with
            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)

    #Hue simplification
    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]:
                #White is skipped
                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:
        #Sort illustrations by tone
        ToneExtract(fileNm, output_path + fileNm + '_tone')

        #grayscale
        Grayscale(fileNm, output_path + fileNm + '_grayscale')

        #Extract the intensity of saturation (red)->Green->Weak in the order of blue)
        SaidoExtarct(fileNm, output_path + fileNm + '_saido_extract')

        #Simplify 360 patterns of hues
        SimpleHue(fileNm, output_path + fileNm + '_saido_gray')

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



Recommended Posts

Analyze the illustration (Memo)
DJango Memo: From the beginning (preparation)
Illustration of the results of the knapsack problem
DJango Memo: From the beginning (model settings)
[Bash] Let's analyze the Fork bomb now
A memo explaining the axis specification of axis