cv::Mat::copyTo
çıkış matrisi başlatıldı olmasına bağlı olarak iki şeyden birini yapar ile gider. Çıktı matrisiniz başlatılamıyorsa, bir maske ile copyTo
kullanarak, girişle aynı türde yeni bir çıktı matrisi oluşturur ve tüm değerler tüm kanallarda 0 olarak ayarlanır. Bu olduğunda, maske tarafından tanımlanan görüntü verileri, matrisin 0'a ayarlanmış olan geri kalanıyla kopyalanır. Çıkış matrisiniz , başlatılmışsa ve halihazırda içerik içeriyorsa, copyTo
, içinde tanımlanan piksellerin üzerine kopyalar. maskeyi kaynağından ve maskenin parçası olmayan pikselleri hedefte bozulmamış olarak bırakır. Bu nedenle, maske tarafından kaynak görüntüden tanımlanan piksellerin değiştirilmesi, çıktıya kopyalanır.
OpenCV artık kütüphaneyle arabirim kurmak için numpy
kullanıyorsa, her iki yöntemi de yapmak çok kolaydır. Bu yazıda görülen diğer cevaptan ayırt etmek için, ilk yöntem, maskeyi görüntü ile basitçe çarparak gerçekleştirilebilir. girişinizi img
denir ve ben maskesi 2D varsayıyorum nerede ikili maske mask
denir varsayarak, sadece aşağıdakileri yapın:
Yukarıdaki kod olsa varsayar
import numpy as np
import cv2
mask = ... # define mask here
img = cv2.imread(...) # Define input image here
# Create new image
new_image = img * (mask.astype(img.dtype))
her iki img
ve mask
pay aynı sayıda kanalları. Kaynak olarak renkli bir görüntü ve önceden varsaydığım gibi maske 2'yi kullanmanız zorlaşır. Bu nedenle, toplam kanal sayısı 2'dir ve 3 değildir ve bu nedenle yukarıdaki sözdizimi, ikisi arasındaki boyutlar artık uyumlu olmadığından size bir hata verecektir. Renkli görüntüleri kullanırken bunun için yer almanız gerekecek. Bunu, maskeye tek bir üçüncü boyut ekleyerek yapabilirsiniz, böylece yayının avantajından yararlanılabilir.
ikinci yaklaşım için
import numpy as np
import cv2
mask = ... # define mask here
img = cv2.imread(...) # Define input image here
# Create new image
# Case #1 - Other image is grayscale and source image is colour
if len(img.shape) == 3 and len(mask.shape) != 3:
new_image = img * (mask[:,:,None].astype(img.dtype))
# Case #2 - Both images are colour or grayscale
elif (len(img.shape) == 3 and len(mask.shape) == 3) or \
(len(img.shape) == 1 and len(mask.shape) == 1):
new_image = img * (mask.astype(img.dtype))
# Otherwise, we can't do this
else:
raise Exception("Incompatible input and mask dimensions")
, en başka görüntü hedef görüntüye
img
geri maskenin tarafından tanımlanan bu görüntüde içeriğini kopyalamak istediğiniz
other_image
denilen olduğunu varsayalım. Bu durumda, ilk olarak yaptığınız şey, maskenin
numpy.where
'u kullanarak sıfır olmayan tüm konumlarını belirler, ardından bunları kopyalamak istediğiniz konumun yanı sıra resminize dizinlemek veya dilimlemek için bunları kullanın. Ayrıca sadece birinci yaklaşımla gibi iki resim arasında kanal sayısına dikkatli olmak zorunda:
import numpy as np
import cv2
mask = ... # define mask here
img = cv2.imread(...) # Define input image here
other_image = cv2.imread(...) # Define other image here
locs = np.where(mask != 0) # Get the non-zero mask locations
# Case #1 - Other image is grayscale and source image is colour
if len(img.shape) == 3 and len(other_image.shape) != 3:
img[locs[0], locs[1]] = other_image[locs[0], locs[1], None]
# Case #2 - Both images are colour or grayscale
elif (len(img.shape) == 3 and len(other_image.shape) == 3) or \
(len(img.shape) == 1 and len(other_image.shape) == 1):
img[locs[0], locs[1]] = other_image[locs[0], locs[1]]
# Otherwise, we can't do this
else:
raise Exception("Incompatible input and output dimensions")
İşte iki yaklaşımda için bir örnek turu. Çoğu görüntü işleme algoritmasında görülen standart bir test görüntüsü olan Cameraman görüntüsünü kullanacağım.
Ben de yapay o gri tonlarında görsel oluyor ama şiddetler tüm kanallara üzerine kopyalanır rağmen, görüntü rengini yaptık. Ben de ilk 100 x 100 alt bölgesine sol basitçe bir maske tanımlamak için gidiyorum ve bu yüzden bir çıkış görüntüsü oluşturur yalnızca kopyalar bu alt bölge:
import numpy as np
import cv2
# Define image
img = cv2.imread("cameraman.png")
# Define mask
mask = np.zeros(img.shape, dtype=np.bool)
mask[:100, :100] = True
ilk yöntemini kullandığınızda ve ne zaman biz sonuçlarını gösterir, elde ederiz:
Biz üst alt bölgesine 0'a Bu eşit ayarlanmış piksel geri kalanı ile bizim görüntü verilerini içeren 100 x 100 sol bir çıkış görüntü oluşturdu görebilirsiniz
maske konumlarına tabidir True
olarak ayarlayın. İkinci yaklaşım için, diğer görüntülerin, tüm kanallar için [0, 255]
'dan gelen giriş görüntüsü ile aynı boyutta rastgele olan bir resim oluşturacağız. ikinci yaklaşımla kod üzerinden çalıştırmak sonra
# Define other image
other_image = (255*np.random.rand(*img.shape)).astype(np.uint8)
, şimdi bu resim olsun:
Gördüğünüz gibi, görüntünün sol üst köşesi olarak güncellendi True
olarak ayarlanmış olan maske konumlarına tabidir.
Teşekkür ederim, parlak bir açıklama ve tabi ki - işe yarıyor! – mikevanis
Çok teşekkürler! Yardımcı olduğuma sevindim. – rayryeng