Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Berikan anda topi Santa menggunakan Python

Berikan anda topi Santa menggunakan Python

WBOY
WBOYke hadapan
2023-04-12 17:22:101689semak imbas

Krismas akan datang Walaupun kita tidak dapat meraikan percutian ini, kita masih perlu menyertai keseronokan ini topi ke avatar

Persediaan pengetahuan asas

Dalam komputer, imej disimpan dalam bentuk matriks, baris pertama dan lajur kedua. Oleh itu, imej dengan lebar × tinggi × saluran warna = 480 × 256 × 3 akan disimpan dalam tensor tiga dimensi 256 × 480 × 3. Pemprosesan imej juga dikira mengikut idea ini (termasuk pemprosesan imej di bawah OpenCV), iaitu, ketinggian × lebar × saluran warna.

Imej Digital

Untuk imej digital, apa yang kita lihat ialah gambar sebenar yang boleh dilihat dengan mata kasar, tetapi pada komputer, imej ini hanyalah sekumpulan titik kecerahan yang berbeza. Imej bersaiz M × N boleh diwakili oleh matriks M × N Nilai elemen matriks mewakili kecerahan piksel pada kedudukan ini Secara umumnya, semakin besar nilai piksel, semakin cerah titik.

Secara umumnya, imej skala kelabu diwakili oleh matriks 2 dimensi dan imej warna (berbilang saluran) diwakili oleh matriks 3 dimensi (M × N × 3).

Saluran imej

menerangkan piksel Jika ia adalah skala kelabu, maka hanya satu nilai diperlukan untuk menerangkannya, iaitu satu saluran. Jika piksel mempunyai tiga warna, RGB, untuk menerangkannya, ia mempunyai tiga saluran. Imej empat saluran ialah R, G, B ditambah saluran A, menunjukkan ketelusan. Biasanya dipanggil saluran alfa, menunjukkan ketelusan.

ROI dan topeng

Menetapkan Wilayah Minat (ROI), diterjemahkan ke dalam bahasa vernakular sebagai, menetapkan wilayah yang diminati. Topeng ialah proses penyamaran imej, yang bersamaan dengan menutup bahagian yang kita tidak peduli, meninggalkan bahagian ROI. Alpha yang disebutkan di atas boleh digunakan sebagai topeng.

Pengetahuan Matrix (Numpy)

Pengindeksan matriks, penghirisan, dsb. Saya tidak menguasainya dengan baik di sini, jadi saya tidak akan membincangkan butirannya sendiri.

Persediaan alam sekitar

Sekarang kita mempunyai pengetahuan asas, mari kita lihat secara ringkas kod tersebut.

Mula-mula pasang perpustakaan OpenCV dan dlib yang perlu anda gunakan, gunakan pip untuk memasang masing-masing

pip install python-opencv

pip install dlib

Kemudian muat turun fail model data shape_predictor_5_face_landmarks.dat secara manual daripada Internet , alamatnya adalah seperti berikut: http://dlib.net/files/, muat turun dan letakkan dalam direktori projek.

Pelajar yang berminat boleh bermain dengan shape_predictor_68_face_landmarks.dat, yang mengenali sebanyak 68 perkara utama pada muka.

Berikan anda topi Santa menggunakan Python

Pemprosesan Kod

Pemprosesan Topi

Perkara pertama yang perlu kami lakukan ialah memproses gambar yang kami gunakan adalah sebagai berikut

Berikan anda topi Santa menggunakan Python

Mula-mula ekstrak nilai rgb dan alpha ​​​​dari imej topi

# 帽子Berikan anda topi Santa menggunakan Python
hat_img3 = cv2.imread("hat.png", -1)
r, g, b, a = cv2.split(hat_img3)
rgb_hat = cv2.merge((r, g, b))
cv2.imwrite("rgb_hat.jpg", rgb_hat)
cv2.imwrite("alpha.jpg", a)
print(a)
print(hat_img3.shape)
print(rgb_hat.shape)

Kesan yang kita dapat adalah seperti berikut:

imej rgb

Berikan anda topi Santa menggunakan Python

graf alfa

Berikan anda topi Santa menggunakan Python

Nilai cetakan a ialah seperti berikut:

[[0 0 0 ... 0 0 0]
 [0 0 0 ... 0 0 0]
 [0 0 0 ... 0 0 0]
 ...
 [0 0 0 ... 0 0 0]
 [0 0 0 ... 0 0 0]
 [0 0 0 ... 0 0 0]]

Pengesanan muka

Berikut ialah pengesanan muka, menggunakan pemprosesan dlib.

# 人脸检测
dets = self.detector(img, 1)
x, y, w, h = dets[0].left(), dets[0].top(), dets[0].right() - dets[0].left(), dets[0].bottom() - dets[0].top()
# 关键点检测
shape = self.predictor(img, dets[0])
point1 = shape.parts()[0]
point2 = shape.parts(2)
# 求两点中心
eyes_center = ((point1.x + point2.x) // 2, (point1.y + point2.y) // 2)

Langkah seterusnya ialah mengecilkan gambar topi

# 帽子和人脸转换比例
hat_w = int(round(dets[0].right()/1.5))
hat_h = int(round(dets[0].bottom() / 2))
if hat_h > y:
hat_h = y - 1
hat_newsize = cv2.resize(rgb_hat, (hat_w, hat_h))
mask = cv2.resize(a, (hat_w, hat_h))
mask_inv = cv2.bitwise_not(mask)
dh = 0
dw = 0

bg_roi = img[y+dh-hat_h:y+dh,(eyes_center[0]-hat_w//3):(eyes_center[0]+hat_w//3*2)]

Pengestrakan ROI

Lakukan pengekstrakan ROI

# 用alpha通道作为mask
mask = cv2.resize(a, (resized_hat_w, resized_hat_h))
mask_inv = cv2.bitwise_not(mask)

pembolehubah topeng mengeluarkan kawasan topi.

Berikan anda topi Santa menggunakan Python

pembolehubah mask_inv digunakan untuk mengekstrak kawasan di mana topi dipasang pada imej muka.

Berikan anda topi Santa menggunakan Python

Seterusnya, keluarkan kawasan (ROI) di mana topi dipasang pada gambar muka

# 原图ROI
# bg_roi = img[y+dh-resized_hat_h:y+dh, x+dw:x+dw+resized_hat_w]
bg_roi = img[y + dh - resized_hat_h:y + dh,
 (eyes_center[0] - resized_hat_w // 3):(eyes_center[0] + resized_hat_w // 3 * 2)]

Kemudian seterusnya , keluarkan kawasan di mana topi dipasang (ROI) Keluarkan kawasan berbentuk topi dari gambar muka

# 原图ROI中提取放帽子的区域
bg_roi = bg_roi.astype(float)
mask_inv = cv2.merge((mask_inv, mask_inv, mask_inv))
alpha = mask_inv.astype(float) / 255
# 相乘之前保证两者大小一致(可能会由于四舍五入原因不一致)
alpha = cv2.resize(alpha, (bg_roi.shape[1], bg_roi.shape[0]))
# print("alpha size: ",alpha.shape)
# print("bg_roi size: ",bg_roi.shape)
bg = cv2.multiply(alpha, bg_roi)
bg = bg.astype('uint8')

Di sini, jenis uint8 lalai gambar ditukar menjadi jenis apungan untuk operasi, dan akhirnya ditukar kembali.

Gambar tersintesis

Berikan anda topi Santa menggunakan Python

Bahagian gelap ialah tempat kita nak letak topi.

Ekstrak bahagian topi daripada gambar topi.

# 提取帽子区域
hat = cv2.bitwise_and(resized_hat, resized_hat, mask=mask)

Gunakan imej topi yang baru anda ubah saiz untuk ekstrak.

Berikan anda topi Santa menggunakan Python

可以看到,除了帽子部分,其他区域已经掩模处理了。

以上就是提取ROI的过程,比较难懂,需要好好琢磨,尤其是矩阵的切片、mask处理部分。

合成Berikan anda topi Santa menggunakan Python

最后一步就是把人脸Berikan anda topi Santa menggunakan Python与帽子合成到一起了,也就是把人脸空余帽子部分的Berikan anda topi Santa menggunakan Python区域和帽子只展示帽子区域的Berikan anda topi Santa menggunakan Python区域(有点拗口)合并在一起。

# 相加之前保证两者大小一致(可能会由于四舍五入原因不一致)
hat = cv2.resize(hat, (bg_roi.shape[1], bg_roi.shape[0]))
# 两个ROI区域相加
add_hat = cv2.add(bg, hat)

效果如下:

Berikan anda topi Santa menggunakan Python

刚刚好,完美叠加Berikan anda topi Santa menggunakan Python。

最后把这个片段放回人脸原图中,展示Berikan anda topi Santa menggunakan Python

img[y+dh-hat_h:y+dh, (eyes_center[0]-hat_w//3):(eyes_center[0]+hat_w//3*2)] = add_hat

Berikan anda topi Santa menggunakan Python

美美的Berikan anda topi Santa menggunakan Python就出来啦!

我们再尝试几张不同的Berikan anda topi Santa menggunakan Python。

Berikan anda topi Santa menggunakan Python

Berikan anda topi Santa menggunakan Python

整体效果还不错哦,需要注意的是,在测试的时候,我们尽量选择人脸占比比较大的Berikan anda topi Santa menggunakan Python来合成,效果要好很多哦~

Atas ialah kandungan terperinci Berikan anda topi Santa menggunakan Python. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:51cto.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam