日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

实现抠图替换背景图

發布時間:2024/3/13 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 实现抠图替换背景图 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

簡述

在上一篇博客進行了證件照更換背景顏色,純藍色,紅色,白色之間的替換,有人私信我,可以不可以把背景換成其他圖片,而不是單純的顏色填充。這在photoshop里面就是選中一個圖層然后復制到另外一張圖片上去,用代碼實現的話和上篇博文換純色背景思路完全一樣,只是在替換顏色時候有了新變化。

獲取目標區域(摳圖)

將目標區域和背景分離開。

此方法摳圖只適合顏色對比比較明顯的圖片,允許存在少量顏色干擾

加載&縮放

通過imread函數加載圖片,resize函數對圖像進行縮放。?
(因為找的圖片有些大,顯示器太小,所以適當縮放)

import cv2 import numpy as npimg=cv2.imread('zjz.jpg') img_back=cv2.imread('back.jpg') #日常縮放 rows,cols,channels = img_back.shape img_back=cv2.resize(img_back,None,fx=0.7,fy=0.7) cv2.imshow('img_back',img_back)rows,cols,channels = img.shape img=cv2.resize(img,None,fx=0.4,fy=0.4) cv2.imshow('img',img) rows,cols,channels = img.shape#rows,cols最后一定要是前景圖片的,后面遍歷圖片需要用到
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

兩張圖片如下?
?
(圖片源于網絡,已經馬賽克處理,如有侵權,私信立即刪除)

要實現的效果就是,把人物圖像摳出來,放在背景圖片上面。

獲取背景區域

由于背景純藍色,所以找到了這些區域,相反的就是我們想要的。?
這里要用到inRange這個函數獲取藍色區域。?
首先需要將圖片轉換為HSV類型。

#轉換hsv hsv=cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
  • 1
  • 2

獲取mask得到藍色區域

#獲取mask lower_blue=np.array([78,43,46]) upper_blue=np.array([110,255,255]) mask = cv2.inRange(hsv, lower_blue, upper_blue) cv2.imshow('Mask', mask)
  • 1
  • 2
  • 3
  • 4
  • 5

藍色區域mask如下圖?
?
黑色區域有明顯白點,有少量的顏色干擾,需要進一步優化。

mask優化

通過腐蝕和膨脹操作進行消除個別白點。?
我對于腐蝕和膨脹操作的理解是:

腐蝕操作將會腐蝕圖像中白色像素,以此來消除小斑點,?
而膨脹操作將使剩余的白色像素擴張并重新增長回去。


#腐蝕膨脹 erode=cv2.erode(mask,None,iterations=1) cv2.imshow('erode',erode) dilate=cv2.dilate(erode,None,iterations=1) cv2.imshow('dilate',dilate)
  • 1
  • 2
  • 3
  • 4
  • 5

優化后如下圖?
?
黑色區域內白點已經消除,完美分離人物與背景[傲嬌]。

替換背景圖片

此時已經將圖片目標區域摳出來了,只需要再新的背景圖上把摳出來的對應點顏色填充上去就好。?
我們首先要確定一個坐標點,這個點決定了要把摳出來的圖像放到新背景圖片的什么位置,即就是摳出圖片左上角(0,0)點在新的背景圖片中應該在的位置。?
注意:

扣出的圖片應該小于背景圖片,確定位置時候應注意,坐標越界后?
會發生異常。注意協調。

#遍歷替換 center=[50,50]#在新背景圖片中的位置 for i in range(rows):for j in range(cols):if dilate[i,j]==0:#0代表黑色的點img_back[center[0]+i,center[1]+j]=img[i,j]#此處替換顏色,為BGR通道 cv2.imshow('res',img_back)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

最終效果?
?
(圖片源于網絡,已經馬賽克處理,如有侵權,私信立即刪除)

總結

基本原理和上篇博客所講相同,重點在于后面的center點的確定(謹防越界),和不同圖片間相對應的坐標和顏色的相互復制替換。

完整代碼如下:

import cv2 import numpy as npimg=cv2.imread('zjz.jpg') img_back=cv2.imread('back.jpg') #日常縮放 rows,cols,channels = img_back.shape img_back=cv2.resize(img_back,None,fx=0.7,fy=0.7) cv2.imshow('img_back',img_back)rows,cols,channels = img.shape img=cv2.resize(img,None,fx=0.4,fy=0.4) cv2.imshow('img',img) rows,cols,channels = img.shape#rows,cols最后一定要是前景圖片的,后面遍歷圖片需要用到#轉換hsv hsv=cv2.cvtColor(img,cv2.COLOR_BGR2HSV) #獲取mask lower_blue=np.array([78,43,46]) upper_blue=np.array([110,255,255]) mask = cv2.inRange(hsv, lower_blue, upper_blue) cv2.imshow('Mask', mask)#腐蝕膨脹 erode=cv2.erode(mask,None,iterations=1) cv2.imshow('erode',erode) dilate=cv2.dilate(erode,None,iterations=1) cv2.imshow('dilate',dilate)#遍歷替換 center=[50,50]#在新背景圖片中的位置 for i in range(rows):for j in range(cols):if dilate[i,j]==0:#0代表黑色的點img_back[center[0]+i,center[1]+j]=img[i,j]#此處替換顏色,為BGR通道 cv2.imshow('res',img_back)cv2.waitKey(0) cv2.destroyAllWindows()

總結

以上是生活随笔為你收集整理的实现抠图替换背景图的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。