I've been struggling to get efficient live imageshow in matplotlib (subplots and cmap) and then use the figure as a display in CV2 for real time, and to this day I remain unsatisfied mainly due to laggy low fps. I have shown the relevant part of the code but if someone want to have the full running code please follow the link to download the data and the python file.
I am eager to have a high fps of like 60+ not sure how is that possible. I have seen some topics where pyqtgraph module is recommended but I am not sure how my NumPy array will be mapped and normalized in the inferno map with the colorbars to be used with pyqtgraph.
Any kind of assistance is much appritiated. Thanks a lot
Link for the data file to be loaded by the python
Sample output via copencv using matplotlib subplots and mapping
(Please refer to the full python script for a running version of the complete code)
#%% Show Live Image using OpenCV
def get_image_data_for_opencv(img_id):
global last_img
global opencv_img
plt_N = len (last_img)
if not plt_N == 0:
plt_cols = 2
plt_rows = int(math.ceil(plt_N / plt_cols))
gs = gridspec.GridSpec(plt_rows, plt_cols)
fig = plt.figure(figsize=(15,10))
fig.suptitle("Real-Time Thermal Imaging from Thermal Cameras")
plt.ioff()
for n, opencv_window_name in enumerate( last_img.keys() ):
if not system_settings["OpenCV_Rescale_Image_Percent"] is False and isinstance( system_settings["OpenCV_Rescale_Image_Percent"], (int,float) ):
if system_settings["OpenCV_Rescale_Image_Percent"] > 0:
last_img[opencv_window_name] = rescale_frame( last_img[opencv_window_name], system_settings["OpenCV_Rescale_Image_Percent"] )
plt.subplot(gs[n])
plt.imshow(last_img[opencv_window_name], cmap="inferno")
plt.colorbar(label='Temperature / °C')
plt.title(opencv_window_name + " - " + str(img_id))
fig.canvas.draw()
opencv_img = np.frombuffer(fig.canvas.tostring_rgb(), dtype=np.uint8)
opencv_img = opencv_img.reshape(fig.canvas.get_width_height()[::-1] + (3,))
plt.close()
# img is rgb, convert to opencv's default bgr
opencv_img = cv2.cvtColor(opencv_img,cv2.COLOR_RGB2BGR)
# cv2.imshow("Live Camera Feeds", img)
# cv2.waitKey(1)
#%% Main System
if __name__ == "__main__":
system_settings = {}
system_settings["OpenCV_Rescale_Image_Percent"] = False
opencv_img = None
last_img = {}
data = retrieveVariableWP("last_img2.pkl")
new_data = {}
for d in data.keys():
for i in range ( len( data[d] ) ):
if not d in new_data:
new_data[d] = [ np.array( data[d][i] ) ]
else:
new_data[d] += [ np.array( data[d][i] ) ]
total_img_frames = max(len(data[x]) for x in data.keys())
img_id=0
while True:
for img_id in range(total_img_frames):
for d in new_data.keys():
width = new_data[d][img_id].shape[0]
height = new_data[d][img_id].shape[1]
ROI_x=[0, -int( round_half_away_from_zero( height*2.5/100 ) )]
ROI_y=[0, -int( round_half_away_from_zero( width*2.5/100 ) )]
if d == "PT1000ST_FLR1":
print ("PT1000ST_FLR1")
img_cv_data = pd.DataFrame(new_data[d][img_id]).apply(counts2temp, args=("1"))
elif d == "FLIR_AX5":
print ("FLIR_AX5")
img_cv_data = pd.DataFrame(new_data[d][img_id]).apply(counts2temp, args=("2"))
else:
print ("ELSE")
img_cv_data = pd.DataFrame(new_data[d][img_id])
last_img[d] = img_cv_data.to_numpy(dtype=float)[ROI_x[0]:ROI_x[1],ROI_y[0]:ROI_y[1]]
get_image_data_for_opencv(img_id)
cv2.imshow("Live Camera Feeds", opencv_img)
cv2.waitKey(1)