本文介绍了我怎样才能柔化这张图片的边缘的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 python 和 opencv 使用蒙版剪切图像.蒙版本身非常参差不齐,因此生成的图像在边缘周围变得有点参差不齐,如下所示

导入 cv2将 numpy 导入为 np导入 skimage.exposure# 加载带有 alpha 通道的图像img = cv2.imread('lena_circle.png', cv2.IMREAD_UNCHANGED)# 只提取 bgr 通道bgr = img[:, :, 0:3]# 提取alpha通道a = img[:, :, 3]# 模糊alpha通道ab = cv2.GaussianBlur(a, (0,0), sigmaX=2, sigmaY=2, borderType = cv2.BORDER_DEFAULT)# 拉伸,使 255 ->255 和 127.5 ->0aa = skimage.exposure.rescale_intensity(ab, in_range=(127.5,255), out_range=(0,255))# 用新的 alpha 通道替换输入中的 alpha 通道out = img.copy()out[:, :, 3] = aa# 保存输出cv2.imwrite('lena_circle_antialias.png', out)# 显示各种图片看步骤# 注意:输入和输出显示严重的锯齿.这似乎是 imshow() 的人工制品,它没有为我显示透明度.但是,保存的图像看起来不错cv2.imshow('In',img)cv2.imshow('BGR', bgr)cv2.imshow('A', a)cv2.imshow('AB', ab)cv2.imshow('AA', aa)cv2.imshow('出',出)cv2.waitKey(0)cv2.destroyAllWindows()


我绝不是 OpenCV 的专家.我查看了 cv2.normalize(),但看起来我无法提供自己的输入和输出值集.所以我还尝试使用以下添加剪辑以确保没有溢出或下溢:

aa = a*2.0 - 255.0aa[aa0] = 255


在那里我通过求解联立方程计算得出,in=255 变为 out=255 和 in=127.5 变为 out=0 并在以下之间进行线性拉伸:

C = A*X+B255 = A*255+B0 = A*127.5+B因此 A=2 和 B=-127.5


但这几乎不如 skimage rescale_intensity.

I am using python and opencv to cut an image using a mask. The mask itself is quite jagged and so the resulting image becomes a bit jagged around the edges like below

Jagged image

Is there a way I can smooth out the edges so they look more like this without affecting the rest of the image?

Smoothed edge

ThanksSoS

** UPDATE **

Added the original jagged image without the annotationOriginal Jagged image

解决方案

Here is one way using OpenCV, Numpy and Skimage. I assume you actually have an image with a transparent background and not just checkerboard pattern.

Input:

import cv2
import numpy as np
import skimage.exposure


# load image with alpha channel
img = cv2.imread('lena_circle.png', cv2.IMREAD_UNCHANGED)

# extract only bgr channels
bgr = img[:, :, 0:3]

# extract alpha channel
a = img[:, :, 3]

# blur alpha channel
ab = cv2.GaussianBlur(a, (0,0), sigmaX=2, sigmaY=2, borderType = cv2.BORDER_DEFAULT)

# stretch so that 255 -> 255 and 127.5 -> 0
aa = skimage.exposure.rescale_intensity(ab, in_range=(127.5,255), out_range=(0,255))

# replace alpha channel in input with new alpha channel
out = img.copy()
out[:, :, 3] = aa

# save output
cv2.imwrite('lena_circle_antialias.png', out)

# Display various images to see the steps
# NOTE: In and Out show heavy aliasing. This seems to be an artifact of imshow(), which did not display transparency for me. However, the saved image looks fine

cv2.imshow('In',img)
cv2.imshow('BGR', bgr)
cv2.imshow('A', a)
cv2.imshow('AB', ab)
cv2.imshow('AA', aa)
cv2.imshow('Out', out)

cv2.waitKey(0)
cv2.destroyAllWindows()


I am by no means an expert with OpenCV. I looked at cv2.normalize(), but it did not look like I could provide my own sets of input and output values. So I also tried using the following adding the clipping to be sure there were no over-flows or under-flows:

aa = a*2.0 - 255.0
aa[aa<0] = 0
aa[aa>0] = 255


where I computed that from solving simultaneous equations such that in=255 becomes out=255 and in=127.5 becomes out=0 and doing a linear stretch between:

C = A*X+B
255 = A*255+B
0 = A*127.5+B
Thus A=2 and B=-127.5


But that does not work nearly as well as skimage rescale_intensity.

这篇关于我怎样才能柔化这张图片的边缘的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-11 05:36