Tryag File Manager
Home
||
Turbo Force
||
B-F Config_Cpanel
Current Path :
/
paip
/
script
/
thermal
/
Or
Select Your Path :
Upload File :
New :
File
Dir
//paip/script/thermal/thermalConverter.py
# -*- coding: utf-8 -*- """ Created on Fri Jun 18 11:53:29 2021 @author: chb """ import os import pickle import sys from glob import glob import cmocean import cv2 import matplotlib.pyplot as plt import numpy as np import pandas as pd from sklearn.cluster import DBSCAN STEPS =5 HOME_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), os.pardir) DATA_DIR = 'data' MODULE_DIR = 'util' OUTPUT_DIR = 'out' # set sys path to import PyDBconnector sys.path.append(os.path.join(HOME_PATH, MODULE_DIR)) from PyDBconnector import PyDBconnector # read pgm def readpgm(name, hasMin=False): ''' 160 * 120 pgm image data divide image data , header data :param name: :param hasMin: :return: ''' with open(name) as f: lines = f.readlines() # Ignores commented lines for l in list(lines): if l[0] == '#': lines.remove(l) # Makes sure it is ASCII format (P2) assert lines[0].strip() == 'P2' # Converts data to a list of integers data = [] for line in lines[1:]: data.extend([int(c) for c in line.split()]) if hasMin : return (np.array(data[5:]), (data[1], data[0]), data[2], data[3], data[4]) else : return (np.array(data[3:]), (data[1], data[0]), data[2]) def getCelsiusTem(data : np.array ) -> np.array : ''' calculate celsius temperature from data : x - 273.15 resolution 0.01, scale * 100 so, 100 * x convert to (100 * x - 27315) / 100 :param data: raw image data from pgm :return: celsius temperater array from [data] ''' return_data = data.copy() return ((return_data - 27315) / 100) def ensure_dir(file_path): ''' check file path exists if not, make one :param file_path: write-file path :return: None ''' directory = os.path.dirname(file_path) if not os.path.exists(directory): os.makedirs(directory) def get_temper(data, image_cMap='jet', font_cMap='', epsilon=1., hist=False, plotY=False, writeFileStr=None, black_cord=None, isPredict=False, ignore_cord = [100,95,20], isFlip=False, Dist=0., ntc_temp = 0.1): # H01_0900_20211210025709_farm_image_ther_435202124005.pgm date_str = '.'.join(os.path.basename(data).split(".")[:-1]) dateSplit = date_str.split('_')[0] data, shape, _, max_val_, min_val_ = readpgm(data, hasMin=True) if isFlip: data = cv2.flip(data, 0) data_ = data.copy() x_ind, y_ind = shape data = getCelsiusTem(data) max_val, min_val = np.max(data), np.min(data) if hist: plt.hist(data.reshape(-1), bins=50) img = data.copy().reshape(120, -1) # normalization img_std = (img - min_val) / (max_val - min_val) * 255 img_std = np.array(img_std, dtype=np.uint8) # as dataframe filtered_df = pd.DataFrame(img_std.copy().reshape(-1), columns=['pix_val']) # x, y index for dbscan filtered_df['x'] = filtered_df.index // shape[1] filtered_df['y'] = filtered_df.index % shape[1] filtered_input = filtered_df.copy() filtered_input['real_temp'] = getCelsiusTem((data_ + min_val_)) # filtering by value (range : 0 ~ 255) filtered_input = filtered_input[filtered_input.pix_val > 150] # hyper parameter low_n_group, high_n_group = 2, 20 for num_sample in range(20, 1, -1): model = DBSCAN(eps=epsilon, min_samples=num_sample, n_jobs=-1) pred = model.fit_predict(np.array(filtered_input[['x', 'y']])) filtered_input['group'] = pred # filtered_input ngroup = filtered_input.group.nunique() if ngroup > low_n_group and ngroup < high_n_group: # print(f'num_sample : {num_sample}, num_group : {ngroup}') break filtered_input = filtered_input[filtered_input.group != -1] filtered_input_center = filtered_input.copy().groupby('group').agg({'pix_val': 'max'}).reset_index() result = pd.merge(filtered_input_center, filtered_input, on=['group', 'pix_val']).groupby(['group', 'pix_val']).agg( {'x': 'max', 'y': 'max'}).reset_index() result = result.nlargest(10, 'pix_val') img_color = cv2.cvtColor(img_std, cv2.COLOR_GRAY2RGB) img = img_color.copy() img2 = img_color.copy() if writeFileStr: plt.imsave(writeFileStr, img[:, :, 0], cmap=image_cMap) image_cmap = cv2.imread(writeFileStr) image_cmap = cv2.cvtColor(image_cmap, cv2.COLOR_BGR2RGB) temp_list = [] for df_raw in result.iterrows(): x, y = df_raw[1]['y'], df_raw[1]['x'] tem_idx = filtered_input[(filtered_input.x == y) & (filtered_input.y == x)]['real_temp'] if len(tem_idx) == 0: continue if isPredict: tem_val = round(reg_model.predict(np.vander([tem_idx.values[0]], STEPS + 1))[0], 1) else: tem_val = round(tem_idx.values[0], 1) temp_list.append(tem_val) img2 = cv2.circle(image_cmap, (int(x), int(y)), 2, font_cMap, 1) ## distance value from DB if Dist > 0.: # load dist_model with open(os.path.join(HOME_PATH,'util','thermal_linear.pkl'), 'rb') as f: dist_model = pickle.load(f) # print(f'tempList(Old) : {temp_list}') temp_list = np.round(dist_model.predict( pd.DataFrame(zip(temp_list, [Dist] * len(temp_list)))), 1) # print(f'tempList(New) : {temp_list}') temp_list = sorted(temp_list, reverse=True) if black_cord is not None: black_x, black_y, black_x_delta, black_y_delta = black_cord img_black = getCelsiusTem(data_ + min_val_).reshape(shape[0], -1) min_black, mean_black, max_black = round( np.min(img_black[black_y:black_y + black_y_delta, black_x:black_x + black_x_delta]), 1), \ round(np.mean(img_black[black_y:black_y + black_y_delta, black_x:black_x + black_x_delta]), 1), \ round(np.max(img_black[black_y:black_y + black_y_delta, black_x:black_x + black_x_delta]), 1) ## delta value of ntc delta_ntc = round(ntc_temp - mean_black, 2) # print(f'ntc value : {ntc_temp}, mean_black : {mean_black}, delta : {delta_ntc}') # print(f'temp_list : {temp_list}, {(temp_list + delta_ntc)}') # ntc value .. at result list[0] temp_list = [ntc_temp] + list(np.round(temp_list + delta_ntc, 1)) # img2 = cv2.rectangle(img2, (black_x, black_y), (black_x + black_x_delta, black_y + black_y_delta), font_cMap, 1) else : temp_list = [-1 * ntc_temp] + temp_list img2 = cv2.resize(img2, dsize=(350, 270), interpolation=cv2.INTER_AREA) if writeFileStr: ensure_dir(writeFileStr) plt.imsave(writeFileStr, img2) # plot or not if plotY: plt.show() dict_val[date_str] = [x for x in temp_list if x < 50.] # 50도 이하로 제한 if black_cord is not None: black_val[date_str] = mean_black black_max[date_str] = max_black plt.close() if __name__ == '__main__': ''' @param: 1. data_dir 2. image_name 3. ntc_temp(default : 25.) @attributes from db 1. cam_dist : A distance between the camera and chickens 2. ntc_coord : ntc coordinates [x,y,delta_x,delta_y] ''' # set default values working_dir = sys.argv[1] if len(sys.argv) > 1 else './' #os.chdir(working_dir) data_dir = sys.argv[1] if len(sys.argv) > 1 else '../data/test/' output_dir = sys.argv[1] if len(sys.argv) > 1 else '../data/test/' img_names = os.path.basename(sys.argv[2]) if len(sys.argv) > 2 else glob(data_dir + '20211214192935_farm_image_ther.pgm')[0] try: ntc_temp = float(sys.argv[3]) if len(sys.argv) > 3 else 0.1 except: ntc_temp = 0.1 if not img_names: raise Exception('unable to read image!!!') #with open('pr_model.pickle', 'rb') as f: # reg_model = pickle.load(f) # check dist info exists from DB Dist = 0. Black_coord = None house_id, module_id = os.path.basename(img_names).split('_')[0:2] # print(os.path.basename(img_names).split('_')[0:2]) sql_query = "select cam_dist, ntc_coord from tbl_camera where cam_type = 'ther' and house_id = '" + house_id + "' and module_id = '" + module_id +"' order by create_time desc limit 1" try: dbConn = PyDBconnector() camDist = dbConn.select_from_db(sql_query) # print(f'camDist : {len(camDist)}') if len(camDist) == 1: Dist = float(camDist.cam_dist.values[0]) Black_coord = eval(camDist.ntc_coord.values[0]) # ex ::: eval('[20,0,20,50]') except Exception as e: print(f"exception : {e}") # # ## test setting ######## # Dist = 2. # Black_coord = eval('[1,0,8,20]') # with open('../util/thermal_linear.pkl', 'rb') as f: # dist_model = pickle.load(f) # # ## test code ######## # set dict dict_val = dict() black_val = dict() black_max = dict() image_cMap = cmocean.cm.thermal font_cMap = (0, 255, 0) if len(sys.argv) > 2 : get_temper(data_dir + img_names, image_cMap, font_cMap, writeFileStr=os.path.join(output_dir,os.path.basename(img_names).split('.')[0]+'_thermalTemp.jpg'), black_cord = Black_coord, Dist=Dist, ntc_temp = ntc_temp) else : get_temper(img_names, image_cMap, font_cMap, writeFileStr=os.path.join(output_dir,os.path.basename(img_names).split('.')[0]+'_thermalTemp.jpg'), black_cord = Black_coord, Dist=Dist, ntc_temp = ntc_temp) print(*list(dict_val.values()))