diff --git a/README.md b/README.md index 950531f..c46317b 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,14 @@ $ ./opencv.py
+Changes in opencv.py file: +- Computed temperature for each pixel based on range between min/max of camera +- Based on a temperature threshold, masked the area of interest (in this case hottest) +- Drawing a contour of the masked area on the camera frame to mark hottest area +- Color clustering the mask to get a mean value of the pixels in order to differentiate between regions of temperature. Each cluster's center is computed as a mean and marked by a green dot + +When running the program a window for each will be opened. The cluster number and threshold can be changed in the code in the call of temp_clustering method and hot_area repectively + ## Related projects - https://gitlab.com/netman69/inficam diff --git a/opencv.py b/opencv.py index c07c20c..e4cb377 100755 --- a/opencv.py +++ b/opencv.py @@ -13,6 +13,9 @@ cap = ht301_hacklib.T2SPLUS() window_name = str(type(cap).__name__) cv2.namedWindow(window_name, cv2.WINDOW_NORMAL) +cv2.namedWindow("hottest_area_mask", cv2.WINDOW_NORMAL) +cv2.namedWindow("clustered_temp", cv2.WINDOW_NORMAL) +cv2.namedWindow("Hot_area_Contour", cv2.WINDOW_NORMAL) orientation = 0 # 0, 90, 180, 270 @@ -107,9 +110,42 @@ def get_fps(self): frame = rotate_frame(frame, orientation) + # Mapping temperature to pixels + min_temp = info['Tmin_C'] + max_temp = info['Tmax_C'] + temperature_image = utils.temp_img(frame, min_temp, max_temp) + + # Hottest area segmentation + mask, hottest_area = utils.hot_area(frame, temperature_image, threshold = 28) + cv2.imshow('hottest_area_mask', hottest_area) + + # Contouring the hottest area + cont_frame = utils.contoured_hottest_area(frame, mask) + cv2.imshow('Hot_area_Contour', cont_frame) + + # Color clustering using K-means + clusters, cluster_centers, clustered_temp = utils.temp_clustering(hottest_area, cluster_no = 7) + + # Finding cluster centroid location + centroid_locations = utils.cluster_centroids(cluster_centers, clustered_temp) + clustered_temp[centroid_locations[:, 0], centroid_locations[:, 1]] = (0, 255, 0) + t = '%.2fC' % max_temp + clustered_temp = cv2.putText( + clustered_temp, + '(Exp) PLT: ' + t, + (100, 185), + cv2.FONT_HERSHEY_PLAIN, + 1, + (0, 255, 0), + 1, + cv2.LINE_AA + ) + cv2.imshow('clustered_temp', clustered_temp) + frame = np.kron(frame, np.ones((upscale_factor, upscale_factor, 1))).astype( np.uint8 ) + if draw_temp: utils.drawTemperature( frame, diff --git a/utils.py b/utils.py index 73d3bc2..3de35ce 100755 --- a/utils.py +++ b/utils.py @@ -163,3 +163,52 @@ def get_pos(self, name, annotation_frame, roi): else: pos = name return pos + +def pixel_to_temp(pixel_value, min_temp, max_temp): + return ((pixel_value / 255) * (max_temp - min_temp)) + min_temp + + +def temp_img(frame, min_temp, max_temp): + normalized_image = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) + normalized_image = cv2.normalize(normalized_image, None, 0, 255, cv2.NORM_MINMAX) + return pixel_to_temp(normalized_image, min_temp, max_temp) + + +def hot_area(frame, temperature_image, threshold): + gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) + mask = np.where(temperature_image < threshold, 0, gray) + return mask, cv2.bitwise_and(frame, frame, mask=mask) + + +def contoured_hottest_area(frame, mask): + cont_frame = frame.copy() + contours, hierarchy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) + cv2.drawContours(cont_frame, contours, -1, (0, 255, 0), 2) + return cont_frame + + +def temp_clustering(hottest_area, cluster_no): + pic = cv2.cvtColor(hottest_area, cv2.COLOR_BGR2RGB) + pixel_vals = pic.reshape((-1, 3)) + pixel_vals = np.float32(pixel_vals) + + criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 100, 0.9) + k = cluster_no + retval, labels, centers = cv2.kmeans(pixel_vals, k, None, criteria, 20, cv2.KMEANS_PP_CENTERS) + + centers = np.uint8(centers) + segmented_data = centers[labels.flatten()] + segmented_image = segmented_data.reshape(pic.shape) + return k, centers, cv2.cvtColor(segmented_image, cv2.COLOR_RGB2BGR) + + +def cluster_centroids(cluster_centers, clustered_temp): + centroid_locations = [] + + for row in cluster_centers: + cluster_i = np.where(clustered_temp == row) + center_x = np.mean(cluster_i[0]).astype(int) + center_y = np.mean(cluster_i[1]).astype(int) + centroid_locations.append([center_x, center_y]) + + return np.array(centroid_locations)