파이톤으로 이미지 필터 파라미터를 블랙박스 최적화 탐색하는 필기

배경.


만약 대상의 함수(문제)가 블랙박스식이라면 이 매개 변수는
Blackbox 최적화는 기계 학습 분야에서hyperparameter 최적화(탐색)라고 불린다.
이미지 처리에서도 블랙박스를 최적화하려는 요구가 종종 있다.
예를 들어 자신이 찍은 조금 안 좋은 사진도 매력적인 이미지로 만들고 싶다.이 경우 밝기, 짙은 갈색 필터/필름 필터 등 필터 파라미터를 검색합니다.
(수동으로 발견하면 시간이 한없이 녹아 고통스럽다)
이번에는 문제를 조금 더 간략하게 해서 ImageMagick이 브래지어를 쓴 이미지로 그 브래지어의 파라미터를 추측해 봅시다.
RMMSE를 사용한 이미지 오차
(정합성 보장 값이 낮을수록)
파이톤으로 블랙박스 함수 최적화 노트
https://qiita.com/syoyo/items/6c33acb0fd475e651f2f
파이썬을 통해 외부 프로그램을 실행해서 결과 줄의 노트를 지웁니다
https://qiita.com/syoyo/items/d13af423604192cee41c
Benderopt를 사용하여 ImageMagick을 외부 명령으로 이동합니다.

데이터 및 코드


초점이 맞지 않다

흐린 후
( -blur 27x20 )
from benderopt import minimize
import numpy as np
import logging
import subprocess
import parse

logging.basicConfig(level=logging.DEBUG) # logging.INFO will print less information

blurred_filename = "shimokita-blur.jpg" # convert -blur 27x20
ref_filename = "shimokita.jpeg"

k_num_eval = 10000

def extract_result(lines):
    for line in lines:
        print(line.decode("utf-8"))
        ret = parse.parse("{:g} ({:g})", line.decode("utf-8"))
        if ret:
            return ret[0]

    raise RuntimeError("Failed to extract value from result.")

count = 0

def f(radius, sigma):
    global count

    count += 1

    print("run {} of {} ...".format(count, k_num_eval))
    tmp_filename = "shimokita-tmp.jpg"
    cmd = "convert {} -blur {}x{} {}".format(ref_filename, radius, sigma, tmp_filename)
    ret = subprocess.run(cmd, shell=True)


    # Compare two images using RMSE
    cmp_cmd = "compare -metric rmse {} {} null:".format(tmp_filename, blurred_filename)
    ret = subprocess.run(cmp_cmd, shell=True, capture_output=True)
    # `compare`(ImageMagick) outputs result into stderr, not stdout
    lines = ret.stderr.splitlines()

    val = extract_result(lines)

    return val


# We define the parameters we want to optimize:
optimization_problem_parameters = [
    {
        "name": "radius",
        "category": "uniform",
        "search_space": {
            "low": 0,
            "high": 100,
        }
    },
    {
        "name": "sigma",
        "category": "uniform",
        "search_space": {
            "low": 0,
            "high": 100,
        }
    }
]

# We launch the optimization
best_sample = minimize(f, optimization_problem_parameters, number_of_evaluation=k_num_eval)

print("radius", best_sample["radius"])
print("sigma", best_sample["sigma"])
print("err = ", f(best_sample["radius"], best_sample["sigma"]))

결실


만 번 돌았다.
radius 27.993241302558445
sigma 19.957452459359814

err =  49.5512

Voila!
radius는 27(진가), 28(추정치)와 1개가 다르게 진가와 비슷한 결과를 얻었다.

idiff로 차별을 얻다.

(차는 20배. 차는 2배면 시각적으로 거의 까맣다(=일치)
jpg 압축의 영향이 매우 커 보입니다...
그나저나 100번은 도저히 안 되고 1000번이면 얼마 안 된다.

TODO


베이시안 옵티미제이션 등을 해보고 싶어요.이미지는 비압축 형식(PNG, BMP, TIFF)으로 만듭니다.파일에 결과를 쓰는 유형이라면 디스크 I/O 소비에 신경을 쓴다(SSD라면 수명이 단축될 수 있다)그래서 membidsk를 사용할 수 있을지 생각해볼게요.
Benderopt는 병렬 처리를 지원하지 않기 때문에 다중 루틴이 아닌 외부 프로그램을 실행하면 처리 시간이 걸리기 때문에 병렬 가능한 프로그램 라이브러리를 사용하는 것을 논의합니다.Instagration 이미지 생성(명령선 제어 가능)에 도달하기 위해 모든 Photoshop을 동일한 방법으로 조작합니다

좋은 웹페이지 즐겨찾기