Ruang pas virtual di OpenCV

Apakah Anda memiliki barang yang Anda sukai di toko online, tetapi tidak ingin membelinya tanpa mencobanya? Tentu saja, di beberapa toko ada peluang untuk mencoba pakaian setelah memesan sebelum pembayaran. Namun, menurut statistik, pangsa pesanan online di toko pakaian dan sepatu online meningkat setiap tahun, tetapi bagian pengembalian juga meningkat, jumlahnya mencapai 50-70% - ini adalah biaya logistik yang sangat besar yang dapat dikurangi secara signifikan menggunakan ruang pas online. Bayangkan Anda mengunggah foto Anda, memilih pakaian dan itu ditransfer ke gambar Anda. Kamar pas virtual untuk sepatu sudah ada, mereka bekerja dengan cukup sukses. Beberapa waktu lalu, kami tertarik dengan topik ini, bagaimana dengan pakaian? Karya-karya semacam itu juga ada, tetapi yang kurang berhasil, di banyak di antaranya, selain artikel, tidak ada yang dapat ditemukan,Orang hanya bisa memimpikan contoh yang berhasil. Kami memutuskan untuk memperbaikinya dan mendukung salah satu jaringan di pustaka OpenCV. Apa yang datang dari ini dapat dilihat disampel virtual_try_on.py .



Hasilnya tidak sempurna, tetapi di daerah ini dianggap cukup baik.


Jika Anda ingin tahu bagaimana ruang pas virtual bekerja dan kesulitan apa yang kami temui ketika mengintegrasikan model ke OpenCV - selamat datang di kucing!


2019 CP-VTON . CP-VTON , , (, ). 3D , 3D-. . github. CP-VTON , , .


.



CP-VTON : GMM (Geometric Matching Module) β€” TOM (Try-On Module) β€” .


GMM (I,c,ct), TOM β€” (I,c^,It), Iβ€” , cβ€” , c^β€” GMM, Itβ€” ground truth ( c), ctβ€” ground truth ( , It). , Itc. VITON, Ip. p, , , , (, , ). . , GMM (p,c)c^, ct. TOM (p,c^), IoIt.


p. , . OpenPose. . LIP_JPPNet. OpenCV () sample human_parsing.py.


, β€” , : , , . , .


preprocessing


.


GMM . , , L2βˆ’. . . , . c^ctL1βˆ’loss.


gmm


TOM . Unet. , . Unet , . , Unet . , . Upsample . (encoder) VGG-19. . Unet IrM. cIr, (1βˆ’M)Io.


Io=MβŠ™c+(1βˆ’M)βŠ™Ir


βŠ™β€” .


tom


Try-On β€” IoIt. . , , . L1βˆ’lossperceptual loss. VGG , . VGG β€” , .


OpenCV


. json , OpenPose Caffe, LIP.


, , .


python3 virtual_try_on.py -i person_img.jpg -c cloth.jpg

OpenCV PIL. . LIP , . CP-VTON . , :


shape = (segm > 0).astype(np.float32)
head  = (segm == 1).astype(np.float32) + \
        (segm == 2).astype(np.float32) + \
        (segm == 4).astype(np.float32) + \
        (segm == 13).astype(np.float32)
cloth = (segm == 5).astype(np.float32) + \
        (segm == 6).astype(np.float32) + \
        (segm == 7).astype(np.float32)

, PIL , . human_colormap.mat. ? Matlab . , scipy . () .


– . 16 , .


mask = mask.resize((width // 16, height // 16), Image.BILINEAR)
mask = mask.resize((width, height), Image.BILINEAR)

. . , OpenCV. PIL resize cv.resize .



, PIL resize, β€” cv.resize.


, ? .


mask_pil mask_ocv


, PIL resize, β€” cv.resize.


, . ? , . , – . , bilinear resize bilinear, area. scale factor, 33 = 16 * 2 + 1, OpenCV – 3. , , . . . , . . :


PIL
class BilinearFilter(object):
    """
    PIL bilinear resize implementation
    image = image.resize((image_width // 16, image_height // 16), Image.BILINEAR)
    """
    def _precompute_coeffs(self, inSize, outSize):
        filterscale = max(1.0, inSize / outSize)
        ksize = int(np.ceil(filterscale)) * 2 + 1

        kk = np.zeros(shape=(outSize * ksize, ), dtype=np.float32)
        bounds = np.empty(shape=(outSize * 2, ), dtype=np.int32)

        centers = (np.arange(outSize) + 0.5) * filterscale + 0.5
        bounds[::2] = np.where(centers - filterscale < 0, 0, centers - filterscale)
        bounds[1::2] = np.where(centers + filterscale > inSize, inSize, centers + filterscale) - bounds[::2]
        xmins = bounds[::2] - centers + 1

        points = np.array([np.arange(row) + xmins[i] for i, row in enumerate(bounds[1::2])]) / filterscale
        for xx in range(0, outSize):
            point = points[xx]
            bilinear = np.where(point < 1.0, 1.0 - abs(point), 0.0)
            ww = np.sum(bilinear)
            kk[xx * ksize : xx * ksize + bilinear.size] = np.where(ww == 0.0, bilinear, bilinear / ww)
        return bounds, kk, ksize

    def _resample_horizontal(self, out, img, ksize, bounds, kk):
        for yy in range(0, out.shape[0]):
            for xx in range(0, out.shape[1]):
                xmin = bounds[xx * 2 + 0]
                xmax = bounds[xx * 2 + 1]
                k = kk[xx * ksize : xx * ksize + xmax]
                out[yy, xx] = np.round(np.sum(img[yy, xmin : xmin + xmax] * k))

    def _resample_vertical(self, out, img, ksize, bounds, kk):
        for yy in range(0, out.shape[0]):
            ymin = bounds[yy * 2 + 0]
            ymax = bounds[yy * 2 + 1]
            k = kk[yy * ksize: yy * ksize + ymax]
            out[yy] = np.round(np.sum(img[ymin : ymin + ymax, 0:out.shape[1]] * k[:, np.newaxis], axis=0))

    def imaging_resample(self, img, xsize, ysize):
        height, width, *args = img.shape
        bounds_horiz, kk_horiz, ksize_horiz = self._precompute_coeffs(width, xsize)
        bounds_vert, kk_vert, ksize_vert    = self._precompute_coeffs(height, ysize)

        out_hor = np.empty((img.shape[0], xsize), dtype=np.uint8)
        self._resample_horizontal(out_hor, img, ksize_horiz, bounds_horiz, kk_horiz)
        out = np.empty((ysize, xsize), dtype=np.uint8)
        self._resample_vertical(out, out_hor, ksize_vert, bounds_vert, kk_vert)
        return out


4 , , OpenCV. . , . , . 256 192, . sample . , - , .


P.S. 2020 OpenCV 20-. . !


All Articles