python - 从图像中裁剪圆形缩略图的最简单方法是什么?
问题描述
我正在尝试从此图像中裁剪一个居中(或不居中)的圆圈:
我从有关堆栈溢出的这个主题的现有问题中窃取了这段代码,但是出了点问题:
import cv2
file = 'dog.png'
img = cv2.imread(file)
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
circle = cv2.HoughCircles(img,
3,
dp=1.5,
minDist=10,
minRadius=1,
maxRadius=10)
x = circle[0][0][0]
y = circle[0][0][1]
r = circle[0][0][2]
rectX = (x - r)
rectY = (y - r)
crop_img = img[rectY:(rectY+2*r), rectX:(rectX+2*r)]
cv2.imwrite('dog_circle.png', crop_img)
输出:
Traceback (most recent call last):
File "C:\Users\Artur\Desktop\crop_circle - Kopie\crop_circle.py", line 14, in <module>
x = circle[0][0][0]
TypeError: 'NoneType' object is not subscriptable
cv2.HoughCircles()
似乎产生None
而不是裁剪圆数组。我该如何解决?
解决方案
first:HoughCircles
用于检测图像上的圆圈,而不是裁剪它。
你不能有圆形图像。图像始终为矩形,但某些像素可以是透明的(在 alpha 通道中RGBA
)并且程序不会显示它们。
因此,您可以首先将图像裁剪为正方形,然后添加 alpha 通道,其中包含哪些像素应该可见的信息。在这里,您可以在黑色背景上使用带有白色圆圈的蒙版。最后,您必须将其另存为png
或tiff
因为jpg
无法保留 Alpha 通道。
我为此使用模块PIL
/ pillow
。
我在图像中心裁剪正方形区域,但您可以为此使用不同的坐标。
接下来我创建具有相同大小和黑色背景的灰度图像并绘制白色圆圈/椭圆。
最后,我将此图像作为 Alpha 通道添加到裁剪后的图像并将其另存为png
.
from PIL import Image, ImageDraw
filename = 'dog.jpg'
# load image
img = Image.open(filename)
# crop image
width, height = img.size
x = (width - height)//2
img_cropped = img.crop((x, 0, x+height, height))
# create grayscale image with white circle (255) on black background (0)
mask = Image.new('L', img_cropped.size)
mask_draw = ImageDraw.Draw(mask)
width, height = img_cropped.size
mask_draw.ellipse((0, 0, width, height), fill=255)
#mask.show()
# add mask as alpha channel
img_cropped.putalpha(mask)
# save as png which keeps alpha channel
img_cropped.save('dog_circle.png')
img_cropped.show()
结果
顺便提一句:
在掩码中,您可以使用 0 到 255 之间的值,并且不同的像素可能具有不同的透明度 - 其中一些可以是半透明的以使边框平滑。
如果您想在自己的页面上以 HTML 格式使用它,那么您不必创建圆形图像,因为 Web 浏览器可以圆角图像并将其显示为圆形。为此,您必须使用 CSS。
编辑:面具上有更多圆圈的例子。
from PIL import Image, ImageDraw
filename = 'dog.jpg'
# load image
img = Image.open(filename)
# crop image
width, height = img.size
x = (width - height)//2
img_cropped = img.crop((x, 0, x+height, height))
# create grayscale image with white circle (255) on black background (0)
mask = Image.new('L', img_cropped.size)
mask_draw = ImageDraw.Draw(mask)
width, height = img_cropped.size
mask_draw.ellipse((50, 50, width-50, height-50), fill=255)
mask_draw.ellipse((0, 0, 250, 250), fill=255)
mask_draw.ellipse((width-250, 0, width, 250), fill=255)
# add mask as alpha channel
img_cropped.putalpha(mask)
# save as png which keeps alpha channel
img_cropped.save('dog_2.png')
img_cropped.show()
推荐阅读
- java - 如何更新在java中监听按钮的组件
- javascript - 未兑现承诺的决议
- google-sheets - 如何在A列中搜索所有文本匹配的列并将B列中的所有对应值相加 Excel
- sql - SQL - 删除重复行而不保留原始行
- back4app - 带有java的Android工作室
- pine-script - 根据其他输入选择显示/隐藏输入字段
- python - Face_Recognition 加载编码文件时出现问题
- asp.net-core - AWS Lambda 与 Kestrel .NET Core 性能对比
- python - 将文件从芹菜任务发送到烧瓶路线
- javascript - Javascript - 如何返回数组中最大的四个数字?