Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python中sobel梯度的可视化_Python_Image Processing_Threshold_Sobel - Fatal编程技术网

python中sobel梯度的可视化

python中sobel梯度的可视化,python,image-processing,threshold,sobel,Python,Image Processing,Threshold,Sobel,我试图在Python中实现sobel操作符并将其可视化。然而,我正在为如何做到这一点而挣扎。我有下面的代码,它当前计算每个像素的梯度 from PIL import Image import math def run(): try: image = Image.open("brick-wall-color.jpg") image = image.convert('LA') apply_sobel_masks(image)

我试图在Python中实现sobel操作符并将其可视化。然而,我正在为如何做到这一点而挣扎。我有下面的代码,它当前计算每个像素的梯度

from PIL import Image
import math


def run():

    try:

        image = Image.open("brick-wall-color.jpg")
        image = image.convert('LA')

        apply_sobel_masks(image)

    except RuntimeError, e:
        print e


def apply_sobel_masks(image):

    gx = [
        [-1, 0, 1],
        [-2, 0, 2],
        [-1, 0, 1]
    ]

    gy = [
        [1, 2, 1],
        [0, 0, 0],
        [-1, -2, -1]
    ]

    width, height = image.size

    for y in range(0, height):

        for x in range(0, width):

            gradient_y = (
                gy[0][0] * get_pixel_safe(image, x - 1, y - 1, 0) +
                gy[0][1] * get_pixel_safe(image, x, y - 1, 0) +
                gy[0][2] * get_pixel_safe(image, x + 1, y - 1, 0) +
                gy[2][0] * get_pixel_safe(image, x - 1, y + 1, 0) +
                gy[2][1] * get_pixel_safe(image, x, y + 1, 0) +
                gy[2][2] * get_pixel_safe(image, x + 1, y + 1, 0)
            )

            gradient_x = (
                gx[0][0] * get_pixel_safe(image, x - 1, y - 1, 0) +
                gx[0][2] * get_pixel_safe(image, x + 1, y - 1, 0) +
                gx[1][0] * get_pixel_safe(image, x - 1, y, 0) +
                gx[1][2] * get_pixel_safe(image, x + 1, y, 0) +
                gx[2][0] * get_pixel_safe(image, x - 1, y - 1, 0) +
                gx[2][2] * get_pixel_safe(image, x + 1, y + 1, 0)
            )

            print "Gradient X: " + str(gradient_x) + " Gradient Y: " + str(gradient_y)
            gradient_magnitude = math.sqrt(pow(gradient_x, 2) + pow(gradient_y, 2))

            image.putpixel((x, y), #tbd)


    image.show()


def get_pixel_safe(image, x, y, layer):

    try:
        return image.getpixel((x, y))[layer]

    except IndexError, e:
        return 0


run()
现在,梯度_值通常远远超出0-255范围,例如990.0、1002.0、778等


所以我想做的是想象这个梯度,但我不知道如何。大多数在线资源只提到计算梯度角度和大小,而没有提到如何在图像中表示它。

使用@saurabheights,我能够可视化梯度的大小。我还纠正了一个错误,那就是我在计算每个像素的梯度后编辑它。这是不正确的,因为当内核在一个像素上移动时,它现在使用刚刚编辑的像素的值。更正后的代码如下:

from PIL import Image, ImageFilter
import math


def run():

    try:

        image = Image.open("geo.jpg")
        image = image.convert('LA')
        image = image.filter(ImageFilter.GaussianBlur(radius=1))
        apply_sobel_masks(image)

    except RuntimeError, e:
        print e


def apply_sobel_masks(image):

    gx = [
        [-1, 0, 1],
        [-2, 0, 2],
        [-1, 0, 1]
    ]

    gy = [
        [1, 2, 1],
        [0, 0, 0],
        [-1, -2, -1]
    ]

    width, height = image.size
    gradient_magnitudes = [[0 for x in range(width)] for y in range(height)]
    gradient_max = None
    gradient_min = None

    for y in range(0, height):

        for x in range(0, width):

            gradient_y = (
                gy[0][0] * get_pixel_safe(image, x - 1, y - 1, 0) +
                gy[0][1] * get_pixel_safe(image, x, y - 1, 0) +
                gy[0][2] * get_pixel_safe(image, x + 1, y - 1, 0) +
                gy[2][0] * get_pixel_safe(image, x - 1, y + 1, 0) +
                gy[2][1] * get_pixel_safe(image, x, y + 1, 0) +
                gy[2][2] * get_pixel_safe(image, x + 1, y + 1, 0)
            )

            gradient_x = (
                gx[0][0] * get_pixel_safe(image, x - 1, y - 1, 0) +
                gx[0][2] * get_pixel_safe(image, x + 1, y - 1, 0) +
                gx[1][0] * get_pixel_safe(image, x - 1, y, 0) +
                gx[1][2] * get_pixel_safe(image, x + 1, y, 0) +
                gx[2][0] * get_pixel_safe(image, x - 1, y - 1, 0) +
                gx[2][2] * get_pixel_safe(image, x + 1, y + 1, 0)
            )

            gradient_magnitude = math.ceil(math.sqrt(pow(gradient_x, 2) + pow(gradient_y, 2)))

            if gradient_max is None:
                gradient_max = gradient_magnitude
                gradient_min = gradient_magnitude

            if gradient_magnitude > gradient_max:
                gradient_max = gradient_magnitude

            if gradient_magnitude < gradient_min:
                gradient_min = gradient_magnitude

            gradient_magnitudes[y][x] = gradient_magnitude

    # Visualize the gradients
    for y in range(0, height):

        for x in range(0, width):

            gradient_magnitude = gradient_magnitudes[y][x]
            pixel_value = int(math.floor(255 * (gradient_magnitude - gradient_min) / (gradient_max - gradient_min)))

            image.putpixel((x, y), pixel_value)

    image.show()


def get_pixel_safe(image, x, y, layer):

    try:
        return image.getpixel((x, y))[layer]

    except IndexError, e:
        return 0


run()
从PIL导入图像,ImageFilter
输入数学
def run():
尝试:
image=image.open(“geo.jpg”)
image=image.convert('LA')
image=image.filter(ImageFilter.GaussianBlur(半径=1))
应用遮罩(图像)
除运行时错误外,e:
打印e
def apply_sobel_遮罩(图像):
gx=[
[-1, 0, 1],
[-2, 0, 2],
[-1, 0, 1]
]
gy=[
[1, 2, 1],
[0, 0, 0],
[-1, -2, -1]
]
宽度,高度=image.size
梯度大小=[[0表示范围内的x(宽度)]表示范围内的y(高度)]
梯度_max=无
梯度_min=无
对于范围(0,高度)内的y:
对于范围内的x(0,宽度):
梯度_y=(
gy[0][0]*获得像素安全(图像,x-1,y-1,0)+
gy[0][1]*获得像素安全(图像,x,y-1,0)+
gy[0][2]*获得像素安全(图像,x+1,y-1,0)+
gy[2][0]*获得像素安全(图像,x-1,y+1,0)+
gy[2][1]*获得像素安全(图像,x,y+1,0)+
gy[2][2]*获得像素安全(图像,x+1,y+1,0)
)
梯度_x=(
gx[0][0]*确保像素安全(图像,x-1,y-1,0)+
gx[0][2]*获得像素安全(图像,x+1,y-1,0)+
gx[1][0]*确保像素安全(图像,x-1,y,0)+
gx[1][2]*获得像素安全(图像,x+1,y,0)+
gx[2][0]*确保像素安全(图像,x-1,y-1,0)+
gx[2][2]*获得像素安全(图像,x+1,y+1,0)
)
gradient_magnity=math.ceil(math.sqrt(pow(gradient_x,2)+pow(gradient_y,2)))
如果渐变_max为无:
梯度最大值=梯度大小
梯度最小=梯度大小
如果梯度大小>梯度最大值:
梯度最大值=梯度大小
如果梯度大小<梯度最小值:
梯度最小=梯度大小
梯度大小[y][x]=梯度大小
#将梯度可视化
对于范围(0,高度)内的y:
对于范围内的x(0,宽度):
梯度大小=梯度大小[y][x]
像素值=int(数学地板(255*(梯度大小-梯度最小值)/(梯度最大值-梯度最小值)))
image.putpixel((x,y),pixel_值)
image.show()
def获取像素安全(图像、x、y、图层):
尝试:
返回image.getpixel((x,y))[层]
除索引器外,e:
返回0
运行()

将值带入特定范围的最简单方法是规范化。对于n个值,找到所有这些值的最小值和最大值。对于范围[a,b],将每个值x规格化为:-

x'=a+(b-a)*(x-min)/(max-min)

对于OP的情况,梯度大小的方程式为:-

x'=255*(x最小值)/(最大最小值)


尝试使用渐变幅值图像的最大值和最小值将其规格化为0-255值,即
displayableGradMagnitude=255*(gradMagnitude minGradMagnitude)/(maxGradMagnitude minGradMagnitude)
。谢谢,这非常有效。也许把它作为答案贴出来,这样我就可以给你你的信任了。另外请注意,索尔贝尔卷积核是可分离的。您可以使用[-1,0,1]进行卷积,并在结果上使用转置[1,2,1]进行第二次卷积。这总是更有效,也更容易实现。这两个操作的顺序是不相关的。y导数是通过转置两个核来计算的。@fbailey:对于每一行,do
tmp[x]=in[x-1]-in[x+1]
。然后,对于每列,do
out[y]=tmp[y-1]+2*tmp[y]+tmp[y+1]
。这就是x-导数。很抱歉这里的speudo代码,这些注释框实际上不允许您做更多的事情。但我相信你可以从那里找到答案。请注意,您不需要创建临时映像
tmp
,您可以直接在输出映像中写入这两个步骤中的每一步。但在第二步中,您需要复制要处理的列,这样就不会覆盖仍然需要的数据。有更聪明的方法可以做到这一点,但这是一个较长的故事。@fbailey:您在每个位置使用3x3像素来计算梯度,但chris提到的是,您可以将此处理分为第一个X方向,然后是Y方向计算(将3x3内核分为一个水平向量和一个垂直向量)。读一下冈萨雷斯的DIP,里面有这些信息。另外,我会在12小时内公布答案。