pythonopencv提取圆内图像_python – 使用OpenCV从图像中提取多边形给定...
使用cv2.fillConvexPoly以便您可以指定2D點陣列并定義一個蒙版,該蒙版填充由這些點定義的形狀在蒙版中為白色.如果多邊形中定義的點是凸的(因此名稱為fillConvexPoly),則應該進行一些公平的警告.
然后我們可以將其轉換為布爾蒙版,并使用它來索引圖像以提取出您想要的像素.下面的代碼生成一個名為mask的數組,它將包含要從圖像中保存的像素的布爾掩碼.此外,數組輸出將包含由多邊形定義的所需提取的子圖像.請注意,圖像初始化為完全黑暗,并且要復制的唯一像素是多邊形定義的像素.
假設實際圖像被稱為img,并假設您的x和y點表示圖像中的水平和垂直坐標,您可以執行以下操作:
import numpy as np
import cv2
pts = np.array([[542, 107], [562, 102], [582, 110], [598, 142], [600, 192], [601, 225], [592, 261], [572, 263], [551, 245], [526, 220], [520, 188], [518, 152], [525, 127], [524, 107]], dtype=np.int32)
mask = np.zeros((img.shape[0], img.shape[1]))
cv2.fillConvexPoly(mask, pts, 1)
mask = mask.astype(np.bool)
out = np.zeros_like(img)
out[mask] = img[mask]
除了要復制的區域外,所有都應該是黑色的.如果要顯示此圖像,可以執行以下操作:
cv2.imshow('Extracted Image', out)
cv2.waitKey(0)
cv2.destroyAllWindows()
這將顯示從多邊形點提取的圖像,并等待您按下的鍵.查看完圖像后,只要顯示窗口具有焦點,就可以按任意鍵.
如果要將此圖像保存到文件,請執行以下操作:
cv2.imwrite('output.png', out)
這會將圖像保存到名為output.png的文件中.我指定PNG格式,因為它是無損的.
作為一個簡單的測試,讓我們定義一個300 x 700的白色圖像,這遠遠超出了你定義的最大坐標.讓我們提取出由該多邊形定義的區域,并顯示輸出的外觀.
img = 255*np.ones((300, 700, 3), dtype=np.uint8)
使用上面的測試圖像,我們得到這個圖像:
編輯
如果你想翻譯提取的圖像,使其位于中間,然后在邊界框周圍放置一個正方形,我建議的一個技巧是使用cv2.remap來翻譯圖像.完成后,使用cv2.rectangle繪制正方形.
cv2.remap的工作原理是,對于輸出中的每個像素,您需要指定要在源圖像中訪問像素的位置的空間坐標.因為您最終將輸出移動到圖像的中心,所以需要為目標圖像中的每個x和y位置添加偏移量以獲取源像素.
要找出移動圖像的正確偏移量,只需找出多邊形的質心,轉換多邊形以使質心位于原點,然后重新轉換它以使其位于圖像的中心.
使用我們在上面定義的變量,您可以通過以下方式找到質心:
(meanx, meany) = pts.mean(axis=0)
找到質心后,您將獲取所有點并減去此質心,然后添加適當的坐標以重新轉換到圖像的中心.圖像的中心可以通過以下方式找到:
(cenx, ceny) = (img.shape[1]/2, img.shape[0]/2)
將坐標轉換為整數也很重要,因為像素坐標是這樣的:
(meanx, meany, cenx, ceny) = np.floor([meanx, meany, cenx, ceny]).astype(np.int32)
現在想出偏移量,就像我們之前談到的那樣:
(offsetx, offsety) = (-meanx + cenx, -meany + ceny)
現在,翻譯你的形象.您需要為輸出圖像中的每個像素定義一個映射,對于目標圖像中的每個點(x,y),您需要提供從源采樣的位置.我們計算的偏移量將每個源像素轉換為目標位置.因為我們正在做相反的事情,對于每個目標像素,我們要找到要采樣的源像素,我們必須減去偏移,而不是添加.因此,首先通常定義(x,y)點的網格,然后減去偏移量.完成后,翻譯圖像:
(mx, my) = np.meshgrid(np.arange(img.shape[1]), np.arange(img.shape[0]))
ox = (mx - offsetx).astype(np.float32)
oy = (my - offsety).astype(np.float32)
out_translate = cv2.remap(out, ox, oy, cv2.INTER_LINEAR)
如果我們用上面的例子顯示out_translate,這就是我們得到的:
涼!現在是時候在這個圖像的頂部繪制矩形了.您所要做的就是找出矩形的左上角和右下角.這可以通過獲取多邊形的左上角和右下角并添加偏移量來將這些點移動到圖像的中心來完成:
topleft = pts.min(axis=0) + [offsetx, offsety]
bottomright = pts.max(axis=0) + [offsetx, offsety]
cv2.rectangle(out_translate, tuple(topleft), tuple(bottomright), color=(255,0,0))
如果我們顯示此圖片,我們會得到:
上面的代碼在居中圖像周圍繪制一個帶藍色的矩形.因此,從開始(提取像素區域)到結尾(翻譯和繪制矩形)的完整代碼是:
# Import relevant modules
import numpy as np
import cv2
# Define points
pts = np.array([[542, 107], [562, 102], [582, 110], [598, 142], [600, 192], [601, 225], [592, 261], [572, 263], [551, 245], [526, 220], [520, 188], [518, 152], [525, 127], [524, 107]], dtype=np.int32)
### Define image here
img = 255*np.ones((300, 700, 3), dtype=np.uint8)
# Initialize mask
mask = np.zeros((img.shape[0], img.shape[1]))
# Create mask that defines the polygon of points
cv2.fillConvexPoly(mask, pts, 1)
mask = mask.astype(np.bool)
# Create output image (untranslated)
out = np.zeros_like(img)
out[mask] = img[mask]
# Find centroid of polygon
(meanx, meany) = pts.mean(axis=0)
# Find centre of image
(cenx, ceny) = (img.shape[1]/2, img.shape[0]/2)
# Make integer coordinates for each of the above
(meanx, meany, cenx, ceny) = np.floor([meanx, meany, cenx, ceny]).astype(np.int32)
# Calculate final offset to translate source pixels to centre of image
(offsetx, offsety) = (-meanx + cenx, -meany + ceny)
# Define remapping coordinates
(mx, my) = np.meshgrid(np.arange(img.shape[1]), np.arange(img.shape[0]))
ox = (mx - offsetx).astype(np.float32)
oy = (my - offsety).astype(np.float32)
# Translate the image to centre
out_translate = cv2.remap(out, ox, oy, cv2.INTER_LINEAR)
# Determine top left and bottom right of translated image
topleft = pts.min(axis=0) + [offsetx, offsety]
bottomright = pts.max(axis=0) + [offsetx, offsety]
# Draw rectangle
cv2.rectangle(out_translate, tuple(topleft), tuple(bottomright), color=(255,0,0))
# Show image, wait for user input, then save the image
cv2.imshow('Output Image', out_translate)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.imwrite('output.png', out_translate)
總結
以上是生活随笔為你收集整理的pythonopencv提取圆内图像_python – 使用OpenCV从图像中提取多边形给定...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 博士毕业2年后,他成为985大学副院长
- 下一篇: 在读博士生 2 年实现 Nature、S