Image to radar values

I am trying to do similarly to the topic responded to in:RADAR image for dBZ values

However, here I have a figure with different dimensions and a color palette that is not so simple.

Legend:

image:

Script:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>import numpy as np
import PIL.Image
import matplotlib.pyplot as plt
import matplotlib.cm
# numba is an optional import, just here to make the function run faster
import numba
# Separated this function out since its the majority of the run time and slow
@numba.njit()
def _get_distances(pixel: np.ndarray, calibration_inputs: np.ndarray):
# Create the outarray where each position is the distance from the pixel at the matching index
outarray = np.empty(shape=(calibration_inputs.shape[0]), dtype=np.int32)
for i in range(calibration_inputs.shape[0]):
# Calculate the vector difference
# NOTE: These must be signed integers to avoid issues with uinteger wrapping (see "nuclear gandhi")
diff = calibration_inputs[i] - pixel
outarray[i] = diff[0] ** 2 + diff[1] ** 2 + diff[2] ** 2
return outarray
def _main():
# How many ticks are on the axes in the legend
calibration_point_count = 6
fname = 'C:/Users/lucas-fagundes/Downloads/radar.png'
fname_chart = 'C:/Users/lucas-fagundes/Downloads/chart.png'
# Whether to collect the calibration data or not
setup_mode = False
# The image of the radar screen
img = np.array(PIL.Image.open(fname))
# The chart legend with the colour bars
img_chart = np.array(PIL.Image.open(fname_chart))
if setup_mode:
fig = plt.figure()
plt.title('Select center of colourbar then each tick on legend')
plt.imshow(img_chart)
selections = plt.ginput(calibration_point_count + 1)
# Use the first click to find the horizontal line to read
calibration_x = int(selections[0][1])
calibration_ys = np.array([int(y) for y, x in selections[1:]], dtype=int)
plt.close(fig)
# Request the tick mark values
calibration_values = np.empty(shape=(calibration_point_count,), dtype=float)
for i in range(calibration_point_count):
calibration_values[i] = float(input(f'Enter calibration point value {i:2}: '))
# Create a plot to verify that the bars were effectively captured
for index, colour in enumerate(['red', 'green', 'blue']):
plt.plot(img_chart[calibration_x, calibration_ys[0]:calibration_ys[-1], index],
color=colour)
plt.title('Colour components in legend')
plt.show()
else:
# If you have already run the calibration once, you can put that data here
# This saves you alot of clicking in future runs
calibration_x = 100
calibration_ys = np.array([15, 74, 119, 201, 243, 302], dtype=int)
calibration_values = np.array([0.0, 20.0, 30.0, 45.0, 63.0, 75.0], dtype=float)
# Record the pixel values to match the colours against
calibration_inputs = img_chart[calibration_x, calibration_ys[0]:calibration_ys[-1], :3].astype(np.int32)
# Print this information to console so that you can copy it into the code above and not rerun setup_mode
print(f'{calibration_x = }')
print(f'{calibration_ys = }')
print(f'{calibration_values = }')
# print(f'{calibration_inputs = }')
# Make the output array the same size, but without RGB vector, just a magnitude
arrout = np.zeros(shape=img.shape[:-1], dtype=img.dtype)
# Iterate through every pixel (can be optimized alot if you need to run this frequently)
for i in range(img.shape[0]):
# This takes a while to run, so print some status throughout
print(f'r{i / img.shape[0] * 100:.2f}%', end='')
for j in range(img.shape[1]):
# Change the type so that the subtraction in the _get_distances function works appropriately
pixel = img[i, j, 0:3].astype(np.int32)
# If this pixel is too dark, leave it as 0
if np.sum(pixel) < 100:
continue
# idx contains the index of the closet match
idx = np.argmin(_get_distances(pixel, calibration_inputs))
# Interpolate the value against the chart and save it to the output array
arrout[i, j] = np.interp(idx + calibration_ys[0], calibration_ys, calibration_values)
# Create a custom cmap based on jet which looks the most like the input image
# This step isn't necessary, but helps us compare the input to the output
cmap = matplotlib.colormaps['jet']
cmap.set_under('k') # If the value is below the bottom clip, set it to black
fig, ax = plt.subplots(3, 1, gridspec_kw={'wspace': 0.01, 'hspace': 0.01}, height_ratios=(3, 3, 1))
ax[0].imshow(arrout, cmap=cmap, vmin=0.5); ax[0].axis('off')
ax[1].imshow(img); ax[1].axis('off'); ax[1].sharex(ax[0]); ax[1].sharey(ax[0])
ax[2].imshow(img_chart); ax[2].axis('off')
plt.show()
if __name__ == '__main__':
_main()
</code>
<code>import numpy as np import PIL.Image import matplotlib.pyplot as plt import matplotlib.cm # numba is an optional import, just here to make the function run faster import numba # Separated this function out since its the majority of the run time and slow @numba.njit() def _get_distances(pixel: np.ndarray, calibration_inputs: np.ndarray): # Create the outarray where each position is the distance from the pixel at the matching index outarray = np.empty(shape=(calibration_inputs.shape[0]), dtype=np.int32) for i in range(calibration_inputs.shape[0]): # Calculate the vector difference # NOTE: These must be signed integers to avoid issues with uinteger wrapping (see "nuclear gandhi") diff = calibration_inputs[i] - pixel outarray[i] = diff[0] ** 2 + diff[1] ** 2 + diff[2] ** 2 return outarray def _main(): # How many ticks are on the axes in the legend calibration_point_count = 6 fname = 'C:/Users/lucas-fagundes/Downloads/radar.png' fname_chart = 'C:/Users/lucas-fagundes/Downloads/chart.png' # Whether to collect the calibration data or not setup_mode = False # The image of the radar screen img = np.array(PIL.Image.open(fname)) # The chart legend with the colour bars img_chart = np.array(PIL.Image.open(fname_chart)) if setup_mode: fig = plt.figure() plt.title('Select center of colourbar then each tick on legend') plt.imshow(img_chart) selections = plt.ginput(calibration_point_count + 1) # Use the first click to find the horizontal line to read calibration_x = int(selections[0][1]) calibration_ys = np.array([int(y) for y, x in selections[1:]], dtype=int) plt.close(fig) # Request the tick mark values calibration_values = np.empty(shape=(calibration_point_count,), dtype=float) for i in range(calibration_point_count): calibration_values[i] = float(input(f'Enter calibration point value {i:2}: ')) # Create a plot to verify that the bars were effectively captured for index, colour in enumerate(['red', 'green', 'blue']): plt.plot(img_chart[calibration_x, calibration_ys[0]:calibration_ys[-1], index], color=colour) plt.title('Colour components in legend') plt.show() else: # If you have already run the calibration once, you can put that data here # This saves you alot of clicking in future runs calibration_x = 100 calibration_ys = np.array([15, 74, 119, 201, 243, 302], dtype=int) calibration_values = np.array([0.0, 20.0, 30.0, 45.0, 63.0, 75.0], dtype=float) # Record the pixel values to match the colours against calibration_inputs = img_chart[calibration_x, calibration_ys[0]:calibration_ys[-1], :3].astype(np.int32) # Print this information to console so that you can copy it into the code above and not rerun setup_mode print(f'{calibration_x = }') print(f'{calibration_ys = }') print(f'{calibration_values = }') # print(f'{calibration_inputs = }') # Make the output array the same size, but without RGB vector, just a magnitude arrout = np.zeros(shape=img.shape[:-1], dtype=img.dtype) # Iterate through every pixel (can be optimized alot if you need to run this frequently) for i in range(img.shape[0]): # This takes a while to run, so print some status throughout print(f'r{i / img.shape[0] * 100:.2f}%', end='') for j in range(img.shape[1]): # Change the type so that the subtraction in the _get_distances function works appropriately pixel = img[i, j, 0:3].astype(np.int32) # If this pixel is too dark, leave it as 0 if np.sum(pixel) < 100: continue # idx contains the index of the closet match idx = np.argmin(_get_distances(pixel, calibration_inputs)) # Interpolate the value against the chart and save it to the output array arrout[i, j] = np.interp(idx + calibration_ys[0], calibration_ys, calibration_values) # Create a custom cmap based on jet which looks the most like the input image # This step isn't necessary, but helps us compare the input to the output cmap = matplotlib.colormaps['jet'] cmap.set_under('k') # If the value is below the bottom clip, set it to black fig, ax = plt.subplots(3, 1, gridspec_kw={'wspace': 0.01, 'hspace': 0.01}, height_ratios=(3, 3, 1)) ax[0].imshow(arrout, cmap=cmap, vmin=0.5); ax[0].axis('off') ax[1].imshow(img); ax[1].axis('off'); ax[1].sharex(ax[0]); ax[1].sharey(ax[0]) ax[2].imshow(img_chart); ax[2].axis('off') plt.show() if __name__ == '__main__': _main() </code>
import numpy as np
import PIL.Image

import matplotlib.pyplot as plt
import matplotlib.cm

# numba is an optional import, just here to make the function run faster
import numba

# Separated this function out since its the majority of the run time and slow
@numba.njit()
def _get_distances(pixel: np.ndarray, calibration_inputs: np.ndarray):
    # Create the outarray where each position is the distance from the pixel at the matching index
    outarray = np.empty(shape=(calibration_inputs.shape[0]), dtype=np.int32)
    for i in range(calibration_inputs.shape[0]):
        # Calculate the vector difference
        #   NOTE: These must be signed integers to avoid issues with uinteger wrapping (see "nuclear gandhi")
        diff = calibration_inputs[i] - pixel
        outarray[i] = diff[0] ** 2 + diff[1] ** 2 + diff[2] ** 2
    return outarray


def _main():
    # How many ticks are on the axes in the legend
    calibration_point_count = 6
    fname = 'C:/Users/lucas-fagundes/Downloads/radar.png'
    fname_chart = 'C:/Users/lucas-fagundes/Downloads/chart.png'
    # Whether to collect the calibration data or not
    setup_mode = False
    # The image of the radar screen
    img = np.array(PIL.Image.open(fname))
    # The chart legend with the colour bars
    img_chart = np.array(PIL.Image.open(fname_chart))

    if setup_mode:
        fig = plt.figure()
        plt.title('Select center of colourbar then each tick on legend')
        plt.imshow(img_chart)
        selections = plt.ginput(calibration_point_count + 1)
        # Use the first click to find the horizontal line to read
        calibration_x = int(selections[0][1])
        calibration_ys = np.array([int(y) for y, x in selections[1:]], dtype=int)
        plt.close(fig)
        # Request the tick mark values
        calibration_values = np.empty(shape=(calibration_point_count,), dtype=float)
        for i in range(calibration_point_count):
            calibration_values[i] = float(input(f'Enter calibration point value {i:2}: '))
        # Create a plot to verify that the bars were effectively captured
        for index, colour in enumerate(['red', 'green', 'blue']):
            plt.plot(img_chart[calibration_x, calibration_ys[0]:calibration_ys[-1], index],
                     color=colour)
        plt.title('Colour components in legend')
        plt.show()

    else:
        # If you have already run the calibration once, you can put that data here
        # This saves you alot of clicking in future runs
        calibration_x = 100
        calibration_ys = np.array([15, 74, 119, 201, 243, 302], dtype=int)
        calibration_values = np.array([0.0, 20.0, 30.0, 45.0, 63.0, 75.0], dtype=float)
    # Record the pixel values to match the colours against
    calibration_inputs = img_chart[calibration_x, calibration_ys[0]:calibration_ys[-1], :3].astype(np.int32)
    # Print this information to console so that you can copy it into the code above and not rerun setup_mode
    print(f'{calibration_x = }')
    print(f'{calibration_ys = }')
    print(f'{calibration_values = }')
    # print(f'{calibration_inputs = }')

    # Make the output array the same size, but without RGB vector, just a magnitude
    arrout = np.zeros(shape=img.shape[:-1], dtype=img.dtype)
    # Iterate through every pixel (can be optimized alot if you need to run this frequently)
    for i in range(img.shape[0]):
        # This takes a while to run, so print some status throughout
        print(f'r{i / img.shape[0] * 100:.2f}%', end='')
        for j in range(img.shape[1]):
            # Change the type so that the subtraction in the _get_distances function works appropriately
            pixel = img[i, j, 0:3].astype(np.int32)
            # If this pixel is too dark, leave it as 0
            if np.sum(pixel) < 100:
                continue
            # idx contains the index of the closet match
            idx = np.argmin(_get_distances(pixel, calibration_inputs))
            # Interpolate the value against the chart and save it to the output array
            arrout[i, j] = np.interp(idx + calibration_ys[0], calibration_ys, calibration_values)
    # Create a custom cmap based on jet which looks the most like the input image
    #   This step isn't necessary, but helps us compare the input to the output
    cmap = matplotlib.colormaps['jet']
    cmap.set_under('k')  # If the value is below the bottom clip, set it to black
    fig, ax = plt.subplots(3, 1, gridspec_kw={'wspace': 0.01, 'hspace': 0.01}, height_ratios=(3, 3, 1))
    ax[0].imshow(arrout, cmap=cmap, vmin=0.5); ax[0].axis('off')
    ax[1].imshow(img); ax[1].axis('off'); ax[1].sharex(ax[0]);  ax[1].sharey(ax[0])
    ax[2].imshow(img_chart); ax[2].axis('off')
    plt.show()


if __name__ == '__main__':
    _main()

Below is the error related to the image I have:

The error corresponds to my image having only one dimension, but I am not able to calibrate it. Could you please help me?

1

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật