微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何从图像中过滤特定的图像坐标

如何解决如何从图像中过滤特定的图像坐标

我正在读取图像,获取具有特定亮度值的对象,然后将 X 和 Y 坐标绘制到图像上。

Problem/outliers

但是,有一组巨大异常值,它们都位于图像的矩形部分,其 X 和 Y 坐标是 1110-1977(宽度)和 1069-1905(高度) )。从这里开始,我将遍历图像的这个小正方形部分,并从我预先创建的 x 和 y 数组中删除与此处所示具有相同坐标的任何值。

然而,这会删除更多坐标,例如,X 在 1110-1977 范围内。因此,当我只想过滤中心的正方形时,最终结果是交叉模式过滤。我该怎么做?

enter image description here

代码

from PIL import Image,ImageDraw
import numpy as np
from math import sqrt
imag = Image.open("Centaurus_A-DeNoiseAI-denoise.jpg")
imag = imag.convert ('RGB')
x=[]
y=[]
imag2=Image.open("Cen_A_cropped.jpg")
imag2=imag2.convert('RGB')
r=[]
g=[]
b=[]
width2,height2=imag2.size
for count2 in range(width2):
    for i2 in range(height2):
        X,Y=count2,i2
        (R,G,B)=imag2.getpixel((X,Y))
        r.append(R)
        g.append(G)
        b.append(B)
average_r=sum(r)/len(r)
average_g=sum(g)/len(g)
average_b=sum(b)/len(b)
brightness_average=sqrt(0.299*(average_r**2) + 0.587*(average_g**2) + 0.114*(average_b**2))
print("Avg. brightness "+str(brightness_average))
def calculate_brightness(galaxy,ref_clus,clus_mag):
    delta_b=(galaxy/ref_clus)
    bright=delta_b**2
    mag=np.log(bright)/np.log(2.512)
    return mag+clus_mag
count=0
X,Y = 1556,1568
(R,B) = imag.getpixel((X,Y))
width,height=imag.size
brightness = sqrt(0.299*(R**2) + 0.587*(G**2) + 0.114*(B**2))
print("Magnitude: "+str((calculate_brightness(13050,15.79,3.7))))
reference=brightness_average/(calculate_brightness(13050,3.7)/6.84)
print("Reference: "+str(reference))
for count in range(width):
    for i in range(height):
        X,Y = count,i
        (R,Y))
        brightness = sqrt(0.299*(R**2) + 0.587*(G**2) + 0.114*(B**2))
        if(reference<=brightness<=reference+3):
            x.append(X)
            y.append(Y)

#post processing----------------------------------------------------------------------------------------------------
for x2 in range(1110,1977):
    for y2 in range(1069,1905):
        X,Y=x2,y2
        if(X in x and Y in y):
            x.remove(X)
            y.remove(Y)
#-------------------------------------------------------------------------------------------------------------------
with imag as im:
    delta = 19
    draw = ImageDraw.Draw(im)
    for i in range(len(x)):
        draw.rectangle([x[i-delta],y[i-delta],x[i-delta],y[i-delta]],fill=(0,255,0))

    im.save("your_image.png")

Centaurus_A-DeNoiseAI-denoise.jpg

Cen_A_cropped.jpg

解决方法

您的后处理逻辑有缺陷。您删除了 1110-1977 范围内的一堆 X 值,而不检查其对应的 Y 值是否也在框的范围内。改为删除此代码部分,并在您第一次循环收集 x 和 y 坐标时添加该逻辑。

for count in range(width):
    for i in range(height):
        X,Y = count,i
        if 1110 <= X < 1977 and 1069 <= Y < 1905:    # add these
            continue                                 # two lines
        (R,G,B) = imag.getpixel((X,Y))

但是,有一种更好的方法可以通过使用 numpy 数组来做完全相同的事情。您可以将大量计算向量化,而不是编写显式循环。

import numpy as np
from PIL import Image,ImageDraw

image = Image.open('Centaurus_A-DeNoiseAI-denoise.jpg').convert('RGB')
img1 = np.array(image)
img2 = np.array(Image.open('Cen_A_cropped.jpg').convert('RGB'))

coeffs = np.array([.299,.587,.114])
average = img2.mean(axis=(0,1))
brightness_average = np.sqrt(np.sum(average**2 * coeffs))
reference = brightness_average / (calculate_brightness(13050,15.79,3.7) / 6.84)
print(f'Avg. brightness: {brightness_average}')
print(f'Reference: {reference}')

brightness = np.sqrt(np.sum(img1.astype(int)**2 * coeffs,axis=-1))
accepted_brightness = (brightness >= reference) * (brightness <= reference + 3)
pixels_used = np.ones((img1.shape[:2]),dtype=bool)
pixels_used[1069:1905,1110:1977] = False
rows,cols = np.where(accepted_brightness * pixels_used)

with image as im:
    draw = ImageDraw.Draw(im)
    draw.point(list(zip(cols,rows)),fill=(0,255,0))
    image.save('out.png')

这里使用的主要技巧是在线

rows,cols = np.where(accepted_brightness * pixels_used)

accepted_brightess 是每个像素的二维数组,带有一个布尔值,无论其亮度是否在您的首选范围内。 pixels_used 是另一个二维布尔数组,其中每个像素都是 True,除了要忽略的中心附近框中的像素。这两者的组合为您提供了具有正确亮度且不在中心正方形中的像素坐标。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。