In [1]:
# extract data from heatmaps
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

In [2]:
img = cv.imread("images/heatmap.png")

In [3]:
img.shape


Out[3]:
(288, 432, 3)

In [4]:
# approximate bounding box around the legend
legend_box = [335, 351, 32, 254] # [xmin, xmax, ymin, ymax]

# calibrate legend with data
legend_data = [5, 20] # [val1, val2]
legend_data_px = [(344,216), (344,80)] # [(x,y), (x,y)]
legend_data_px = [(legend_data_px[0][0] - legend_box[0], legend_data_px[0][1] - legend_box[2]),
                  (legend_data_px[1][0] - legend_box[0], legend_data_px[1][1] - legend_box[2])]

# crop
legend_img = img[legend_box[2]:legend_box[3], legend_box[0]:legend_box[1]]
plt.imshow(cv.cvtColor(legend_img, cv.COLOR_BGR2RGB))


Out[4]:
<matplotlib.image.AxesImage at 0x7f6d3c1e2e80>

Legend Calibration

Assume:

1. approx_val = f(R,G,B)

At calibration points:

2. val1 = f(R1,G1,B1) at (x1,y1)
3. val2 = f(R2,G2,B2) at (x2,y2)

At any (x_l,y_l) on the legend:

4. val_l = f(R,G,B) at (x_l,y_l)

If we assume (x_l,y_l) lies on the line joining (x1,y1) and (x2,y2), then val can be calculated at any (x_l,y_l) assuming linear spacing.


In [5]:
# Plot intensity along the legend "line":
ylist = [v for v in range(0,legend_img.shape[0])]
intensity = np.sqrt([legend_img[y,12,0]**2 + legend_img[y,12,1]**2 + legend_img[y,12,2]**2 for y in ylist])
plt.plot(ylist, intensity)


Out[5]:
[<matplotlib.lines.Line2D at 0x7f6d3c12d518>]

In [6]:
# find edges
intensity_jumps = [intensity[i]-intensity[i-1] > 10 for i in range(1,len(intensity))]
intensity_jumps = np.array([j for j in range(0,len(intensity_jumps)) if intensity_jumps[j] == True])
intensity_jumps


Out[6]:
array([  3, 219, 220])

In [7]:
# for smooth legend, it's easy to pick the pick min, max:
# |----|---------x----------|----|----
#      i_min    mid-pt     i_max

i_max = np.min(intensity_jumps[intensity_jumps - len(intensity)/2 > 0]) - 1
i_min = np.max(intensity_jumps[intensity_jumps - len(intensity)/2 < 0]) + 1

print(i_min, i_max)


4 218

In [10]:
# build a list of (r,g,b)->val
rgb_list = [(legend_img[y,12,0], legend_img[y,12,1], legend_img[y,12,2]) for y in range(i_min,i_max)]
val_list = [(legend_data[1] - legend_data[0])*(y - legend_data_px[0][1])/(legend_data_px[1][1] - legend_data_px[0][1]) + legend_data[0] for y in range(i_min,i_max)]
val_list


Out[10]:
[24.852941176470587,
 24.74264705882353,
 24.63235294117647,
 24.522058823529413,
 24.41176470588235,
 24.301470588235293,
 24.191176470588236,
 24.080882352941178,
 23.970588235294116,
 23.860294117647058,
 23.75,
 23.639705882352942,
 23.529411764705884,
 23.419117647058822,
 23.308823529411764,
 23.198529411764707,
 23.08823529411765,
 22.977941176470587,
 22.86764705882353,
 22.75735294117647,
 22.647058823529413,
 22.53676470588235,
 22.426470588235293,
 22.316176470588236,
 22.205882352941178,
 22.095588235294116,
 21.985294117647058,
 21.875,
 21.764705882352942,
 21.654411764705884,
 21.544117647058822,
 21.433823529411764,
 21.323529411764707,
 21.21323529411765,
 21.102941176470587,
 20.99264705882353,
 20.88235294117647,
 20.772058823529413,
 20.661764705882355,
 20.551470588235293,
 20.441176470588236,
 20.330882352941174,
 20.220588235294116,
 20.110294117647058,
 20.0,
 19.889705882352942,
 19.779411764705884,
 19.669117647058826,
 19.558823529411764,
 19.448529411764707,
 19.338235294117645,
 19.227941176470587,
 19.11764705882353,
 19.00735294117647,
 18.897058823529413,
 18.786764705882355,
 18.676470588235293,
 18.566176470588236,
 18.455882352941174,
 18.345588235294116,
 18.235294117647058,
 18.125,
 18.014705882352942,
 17.904411764705884,
 17.794117647058826,
 17.683823529411764,
 17.573529411764707,
 17.463235294117645,
 17.352941176470587,
 17.24264705882353,
 17.13235294117647,
 17.022058823529413,
 16.911764705882355,
 16.801470588235293,
 16.691176470588236,
 16.580882352941174,
 16.470588235294116,
 16.360294117647058,
 16.25,
 16.139705882352942,
 16.029411764705884,
 15.919117647058824,
 15.808823529411764,
 15.698529411764707,
 15.588235294117647,
 15.477941176470589,
 15.367647058823529,
 15.257352941176471,
 15.147058823529411,
 15.036764705882353,
 14.926470588235293,
 14.816176470588236,
 14.705882352941176,
 14.595588235294118,
 14.485294117647058,
 14.375,
 14.264705882352942,
 14.154411764705882,
 14.044117647058824,
 13.933823529411764,
 13.823529411764707,
 13.713235294117647,
 13.602941176470589,
 13.492647058823529,
 13.382352941176471,
 13.272058823529411,
 13.161764705882353,
 13.051470588235293,
 12.941176470588236,
 12.830882352941178,
 12.720588235294118,
 12.610294117647058,
 12.5,
 12.389705882352942,
 12.279411764705882,
 12.169117647058822,
 12.058823529411764,
 11.948529411764707,
 11.838235294117647,
 11.727941176470587,
 11.617647058823529,
 11.507352941176471,
 11.397058823529413,
 11.286764705882353,
 11.176470588235293,
 11.066176470588236,
 10.955882352941178,
 10.845588235294118,
 10.735294117647058,
 10.625,
 10.514705882352942,
 10.404411764705882,
 10.294117647058822,
 10.183823529411764,
 10.073529411764707,
 9.963235294117647,
 9.852941176470587,
 9.742647058823529,
 9.632352941176471,
 9.522058823529413,
 9.411764705882353,
 9.301470588235293,
 9.191176470588236,
 9.080882352941178,
 8.970588235294118,
 8.860294117647058,
 8.75,
 8.639705882352942,
 8.529411764705882,
 8.419117647058822,
 8.308823529411764,
 8.198529411764707,
 8.088235294117647,
 7.977941176470589,
 7.867647058823529,
 7.757352941176471,
 7.647058823529411,
 7.536764705882353,
 7.4264705882352935,
 7.3161764705882355,
 7.205882352941177,
 7.095588235294118,
 6.985294117647059,
 6.875,
 6.764705882352941,
 6.654411764705882,
 6.544117647058823,
 6.4338235294117645,
 6.323529411764706,
 6.213235294117647,
 6.102941176470589,
 5.992647058823529,
 5.882352941176471,
 5.772058823529412,
 5.661764705882353,
 5.551470588235294,
 5.4411764705882355,
 5.330882352941177,
 5.220588235294118,
 5.110294117647059,
 5.0,
 4.889705882352941,
 4.779411764705882,
 4.669117647058823,
 4.5588235294117645,
 4.448529411764706,
 4.338235294117647,
 4.227941176470588,
 4.117647058823529,
 4.007352941176471,
 3.8970588235294117,
 3.7867647058823533,
 3.6764705882352944,
 3.5661764705882355,
 3.4558823529411766,
 3.3455882352941178,
 3.235294117647059,
 3.125,
 3.014705882352941,
 2.9044117647058822,
 2.7941176470588234,
 2.6838235294117645,
 2.573529411764706,
 2.463235294117647,
 2.3529411764705883,
 2.2426470588235294,
 2.1323529411764706,
 2.0220588235294117,
 1.9117647058823528,
 1.801470588235294,
 1.6911764705882355,
 1.5808823529411766,
 1.4705882352941178,
 1.3602941176470589]

In [17]:
# do extraction by finding nearest value and calculate error

def valForRGB(r,g,b):
    return val_list[np.argmin(np.array([(c[0]-r)**2 + (c[1]-g)**2 + (c[2]-b)**2 for c in rgb_list]))]

results = []
for xi in range(125,300,43):
    for yi in range(56,232,43):
        (r,g,b) = (img[yi,xi,0], img[yi,xi,1], img[yi,xi,2])
        results.append((xi,yi,valForRGB(r,g,b)))


/usr/lib/python3.6/site-packages/ipykernel_launcher.py:4: RuntimeWarning: overflow encountered in ubyte_scalars
  after removing the cwd from sys.path.

In [18]:
results


Out[18]:
[(125, 56, 1.3602941176470589),
 (125, 99, 6.102941176470589),
 (125, 142, 11.066176470588236),
 (125, 185, 16.029411764705884),
 (125, 228, 20.99264705882353),
 (168, 56, 2.0220588235294117),
 (168, 99, 7.095588235294118),
 (168, 142, 12.058823529411764),
 (168, 185, 17.022058823529413),
 (168, 228, 22.095588235294116),
 (211, 56, 3.014705882352941),
 (211, 99, 7.977941176470589),
 (211, 142, 13.051470588235293),
 (211, 185, 18.014705882352942),
 (211, 228, 22.977941176470587),
 (254, 56, 4.117647058823529),
 (254, 99, 9.080882352941178),
 (254, 142, 14.044117647058824),
 (254, 185, 19.11764705882353),
 (254, 228, 24.080882352941178),
 (297, 56, 5.0),
 (297, 99, 10.073529411764707),
 (297, 142, 15.036764705882353),
 (297, 185, 20.0),
 (297, 228, 9.742647058823529)]

In [ ]: