Skip to content

Instantly share code, notes, and snippets.

@sansuke05
Last active September 18, 2020 13:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sansuke05/86744543be6bbe2cefe763518083ca8a to your computer and use it in GitHub Desktop.
Save sansuke05/86744543be6bbe2cefe763518083ca8a to your computer and use it in GitHub Desktop.
mask = io.imread('./mask/mask_cynthia.png')
def convert_cynthia_pantie(image):
pantie = np.array(image)
patch = np.copy(pantie[-100:-5, 546:, :])
pantie[-100:, 546:, :] = 0
patch = skt.resize(patch[::-1, ::-1, :],
(patch.shape[0] + 30, patch.shape[1]),
anti_aliasing=True,
mode='reflect')
# パッチを元のパンツに貼りつけ
[pr, pc, d] = patch.shape
pantie[127 - 5:127 - 5 + pr, :pc, :] = np.uint8(patch * 255)
# フロント部分だけ切り出し
front = pantie[:350 - 105, 7:300]
# バック部分の切り出しと左右反転
back = pantie[:350, 300:-10][:, ::-1]
# バック部分を形に合わせて変形
arrx = (np.linspace(0, 1, 25)**2) * 115
arrx[2:14] += np.sin(np.linspace(0, np.pi, 12)) * 7
arry = (np.linspace(0, 1, 25)**2) * 115
arrx -= 60
back = affine_transform_by_arr(back, arrx, arry)
# バック部分を上下反転
back = np.uint8(back[::-1, 7:] * 255)
back = back[3:, 10:10 + front.shape[1]]
# フロントとバックを結合、調整
pantie = np.concatenate((front, back), axis=0)
pantie = np.uint8(resize(pantie, [0.789, 0.878]) * 255)
pantie = np.bitwise_and(pantie, mask)
pantie = np.concatenate((pantie[:, ::-1], pantie), axis=1)
return Image.fromarray(pantie)
@TenteEEEE
Copy link

ありがとうございます!
白くなる問題ですが、これはfront側を21行目でアフィン変換後に0~1の値域のfloat型になり、これを39行目でuint8型のbackと合わせる際に0~255と0~1で値域が異なるため、発色が変になってしまいます。
(なぜかuint8とfloatの配列がエラーもなくひっついてしまうPythonの闇)

以下、解説と細かな最適化を含むコードです。
ご質問あればいつでもまた問い合わせください!

image = Image.open('./dream/0001.png')

def convert_cynthia_pantie(image):
    pantie = np.array(image)
    patch = np.copy(pantie[-100:-5, 546:, :])
    pantie[-100:, 546:, :] = 0
    patch = skt.resize(patch[::-1, ::-1, :],
                       (patch.shape[0] + 30, patch.shape[1]),
                       anti_aliasing=True,
                       mode='reflect')
    [pr, pc, d] = patch.shape
    pantie[127 - 5:127 - 5 + pr, :pc, :] = np.uint8(patch * 255)

    # フロント部分だけ切り出し
    ### Affine Transformはちょっと重いので、切り出し部分で下を多めに切り取るのがおすすめです
    ### また、Affine Transformのあとは0~1のfloatの画像に変換されてしまうので、
    ### uint8に戻す前にbackとconcatenateすると、0~255と0~1で値域が合わず、白色になります
    ### センターのリボンはだいたい左端から7pxぐらいから始まるので、ミラー前提であればここで削ってしまっても構いません
    front = pantie[:350-105, 7:300]

    # バック部分の切り出しと左右反転
    back = pantie[:350, 300:-10][:, ::-1]
    # バック部分を形に合わせて変形
    arrx = (np.linspace(0, 1, 25)**2) * 115
    arrx[2:14] += np.sin(np.linspace(0, np.pi, 12)) * 7
    arry = np.zeros(25)
    arrx -= 70
    back = affine_transform_by_arr(back, arrx, arry)
    # バック部分を上下反転
    back = np.uint8(back[::-1, 7:] * 255)
    back = back[3:, 10:10 + front.shape[1]] ### numpy arrayのスライスは型が変わらないので、再変換がなくても大丈夫です。

    # フロントとバックを結合、調整
    pantie = np.concatenate((front, back), axis=0)
    pantie = np.uint8(resize(pantie, [1.55, 1.745]) * 255)
    pantie = np.concatenate((pantie[:, ::-1], pantie), axis=1)
    return Image.fromarray(pantie) ### 最後はPIL.Imageの形式でリターンする必要があります。

@TenteEEEE
Copy link

正面の裾付近は少し大きめに貼り、マスクで切り取ってしまうのが最もかんたんです。
ただ、20番前後ぐらいまではパンツパッチ純対応パンツではないということもあり、30番以降ぐらいに対応を絞っても良いと思います。

後ろはだいたい合わせたのですが、ここから微調整すれば形は合うと思います。
a

    back = pantie[:400, 300:-10][:, ::-1]
    # バック部分を形に合わせて変形
    arrx = (np.linspace(0, 1, 49)**2) * 115
    arrx[:12] += np.sin(np.linspace(np.pi/2, np.pi, 12)) * 7
    arrx += np.sin(np.linspace(0, np.pi/2, 49))**2 * 40
    arry = (np.linspace(0, 1, 49)**2) * 115
    arrx -= 90
    back = affine_transform_by_arr(back, arrx, arry)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment