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

2024-05-15 03:15:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在读取一幅图像,获取具有特定亮度值的对象,然后绘制图像的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,G,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, 15.79,3.7)/6.84)
print("Reference: "+str(reference))
for count in range(width):
    for i in range(height):
        X,Y = count,i
        (R,G,B) = imag.getpixel((X,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


Tags: in图像forlenrangesqrtjpgdelta
1条回答
网友
1楼 · 发布于 2024-05-15 03:15:37

你的后处理逻辑有缺陷。删除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是每个像素的2d数组,无论其亮度是否在您的首选范围内,都具有布尔值pixels_used是另一个二维布尔数组,其中每个像素都是True,除了框中靠近中心的像素之外,您要忽略。这两种方法的结合将为您提供具有正确亮度且不在中心正方形中的像素坐标

相关问题 更多 >

    热门问题