-
Notifications
You must be signed in to change notification settings - Fork 101
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Temp info getting #23
base: master
Are you sure you want to change the base?
Changes from 11 commits
b2bd7b9
697d7df
e57b353
94c77d6
534addd
48118bf
51714de
1416d25
eb59f26
15b55dd
96f3e03
cbeb0cb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,6 +8,7 @@ | |
#include <iostream> | ||
#include <string> | ||
#include <signal.h> | ||
#include <math.h> | ||
#include <memory> | ||
#include "args.h" | ||
|
||
|
@@ -21,37 +22,129 @@ void handle_sig(int sig) { | |
sigflag = 1; | ||
} | ||
|
||
double device_sensor_to_k(double sensor) { | ||
// formula from http://aterlux.ru/article/ntcresistor-en | ||
double ref_temp = 297.0; // 23C from table | ||
double ref_sensor = 6616.0; // ref value from table | ||
double beta = 200; // best beta coef we've found | ||
double part3 = log(sensor) - log(ref_sensor); | ||
double parte = part3 / beta + 1.0 / ref_temp; | ||
return 1.0 / parte; | ||
} | ||
|
||
double temp_from_raw(int x, double device_k) { | ||
// Constants below are taken from linear trend line in Excel. | ||
// -273 is translation of Kelvin to Celsius | ||
// 330 is max temperature supported by Seek device | ||
// 16384 is full 14 bits value, max possible () | ||
double base = x * 330 / 16384.0; | ||
double lin_k = -1.5276; // derived from Excel linear model | ||
double lin_offset= -470.8979; // same Excel model | ||
return base - device_k * lin_k + lin_offset - 273.0; | ||
} | ||
|
||
void overlay_values(Mat &outframe, Point coord, Scalar color) { | ||
int gap=2; | ||
int arrLen=7; | ||
int weight=1; | ||
line(outframe, coord-Point(-arrLen, -arrLen), coord-Point(-gap, -gap), color, weight); | ||
line(outframe, coord-Point(arrLen, arrLen), coord-Point(gap, gap), color, weight); | ||
line(outframe, coord-Point(-arrLen, arrLen), coord-Point(-gap, gap), color, weight); | ||
line(outframe, coord-Point(arrLen, -arrLen), coord-Point(gap, -gap), color, weight); | ||
} | ||
|
||
void draw_temp(Mat &outframe, double temp, Point coord, Scalar color) { | ||
char txt [64]; | ||
sprintf(txt, "%5.1f", temp); | ||
putText(outframe, txt, coord-Point(20, -20), FONT_HERSHEY_COMPLEX_SMALL, 0.75, color, 1, CV_AA); | ||
} | ||
|
||
// Function to process a raw (corrected) seek frame | ||
void process_frame(Mat &inframe, Mat &outframe, float scale, int colormap, int rotate) { | ||
Mat frame_g8, frame_g16; // Transient Mat containers for processing | ||
void process_frame(Mat &inframe, Mat &outframe, float scale, int colormap, int rotate, int device_temp_sensor) { | ||
Mat frame_g8_nograd, frame_g16; // Transient Mat containers for processing | ||
|
||
// get raw max/min/central values | ||
double min, max, central; | ||
minMaxIdx(inframe, &min, &max); | ||
Scalar valat=inframe.at<uint16_t>(Point(inframe.cols/2.0, inframe.rows/2.0)); | ||
central=valat[0]; | ||
|
||
double device_k=device_sensor_to_k(device_temp_sensor); | ||
|
||
double mintemp=temp_from_raw(min, device_k); | ||
double maxtemp=temp_from_raw(max, device_k); | ||
double centraltemp=temp_from_raw(central, device_k); | ||
|
||
printf("rmin,rmax,central,devtempsns: %d %d %d %d\t", (int)min, (int)max, (int)central, (int)device_temp_sensor); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need to be pushing two lines to stdout for every frame? If these need to stay can you control their output with a command line parameter. |
||
printf("min-max-center-device: %.1f %.1f %.1f %.1f\n", mintemp, maxtemp, centraltemp, device_k-273.0); | ||
|
||
normalize(inframe, frame_g16, 0, 65535, NORM_MINMAX); | ||
|
||
// Convert seek CV_16UC1 to CV_8UC1 | ||
frame_g16.convertTo(frame_g8, CV_8UC1, 1.0/256.0 ); | ||
frame_g16.convertTo(frame_g8_nograd, CV_8UC1, 1.0/256.0 ); | ||
|
||
// Rotate image | ||
if (rotate == 90) { | ||
transpose(frame_g8, frame_g8); | ||
flip(frame_g8, frame_g8, 1); | ||
transpose(frame_g8_nograd, frame_g8_nograd); | ||
flip(frame_g8_nograd, frame_g8_nograd, 1); | ||
} else if (rotate == 180) { | ||
flip(frame_g8, frame_g8, -1); | ||
flip(frame_g8_nograd, frame_g8_nograd, -1); | ||
} else if (rotate == 270) { | ||
transpose(frame_g8, frame_g8); | ||
flip(frame_g8, frame_g8, 0); | ||
transpose(frame_g8_nograd, frame_g8_nograd); | ||
flip(frame_g8_nograd, frame_g8_nograd, 0); | ||
} | ||
|
||
Point minp, maxp, centralp; | ||
minMaxLoc(frame_g8_nograd, NULL, NULL, &minp, &maxp); // doing it here, so we take rotation into account | ||
centralp=Point(frame_g8_nograd.cols/2.0, frame_g8_nograd.rows/2.0); | ||
minp*=scale; | ||
maxp*=scale; | ||
centralp*=scale; | ||
|
||
// Resize image: http://docs.opencv.org/3.2.0/da/d54/group__imgproc__transform.html#ga5bb5a1fea74ea38e1a5445ca803ff121 | ||
// Note this is expensive computationally, only do if option set != 1 | ||
if (scale != 1.0) | ||
resize(frame_g8, frame_g8, Size(), scale, scale, INTER_LINEAR); | ||
resize(frame_g8_nograd, frame_g8_nograd, Size(), scale, scale, INTER_LINEAR); | ||
|
||
// add gradient | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Did you consider extending the image frame do that you don't end up overdrawing the thermal data so much? |
||
Mat frame_g8(Size(frame_g8_nograd.cols+20, frame_g8_nograd.rows), CV_8U, Scalar(128)); | ||
for (int r = 0; r < frame_g8.rows-1; r++) | ||
{ | ||
frame_g8.row(r).setTo(255.0*(frame_g8.rows-r)/((float)frame_g8.rows)); | ||
} | ||
frame_g8_nograd.copyTo(frame_g8(Rect(0,0,frame_g8_nograd.cols, frame_g8_nograd.rows))); | ||
|
||
// Apply colormap: http://docs.opencv.org/3.2.0/d3/d50/group__imgproc__colormap.html#ga9a805d8262bcbe273f16be9ea2055a65 | ||
if (colormap != -1) { | ||
applyColorMap(frame_g8, outframe, colormap); | ||
} else { | ||
cv::cvtColor(frame_g8, outframe, cv::COLOR_GRAY2BGR); | ||
} | ||
|
||
// overlay marks | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All of these overlays need to be controlled by a command line option defaulting to false. |
||
draw_temp(outframe, mintemp, Point(outframe.cols-49, outframe.rows-29), Scalar(255, 255, 255)); | ||
draw_temp(outframe, mintemp, Point(outframe.cols-51, outframe.rows-31), Scalar(0, 0, 0)); | ||
draw_temp(outframe, mintemp, Point(outframe.cols-50, outframe.rows-30), Scalar(255, 0, 0)); | ||
|
||
draw_temp(outframe, maxtemp, Point(outframe.cols-49, 0), Scalar(255, 255, 255)); | ||
draw_temp(outframe, maxtemp, Point(outframe.cols-51, 2), Scalar(0, 0, 0)); | ||
draw_temp(outframe, maxtemp, Point(outframe.cols-50, 1), Scalar(0, 0, 255)); | ||
|
||
draw_temp(outframe, centraltemp, centralp+Point(-1, -1), Scalar(255, 255, 255)); | ||
draw_temp(outframe, centraltemp, centralp+Point(1, 1), Scalar(0, 0, 0)); | ||
draw_temp(outframe, centraltemp, centralp+Point(0, 0), Scalar(128, 128, 128)); | ||
|
||
overlay_values(outframe, centralp+Point(-1,-1), Scalar(0,0,0)); | ||
overlay_values(outframe, centralp+Point(1,1), Scalar(255,255,255)); | ||
overlay_values(outframe, centralp, Scalar(128,128,128)); | ||
|
||
overlay_values(outframe, minp+Point(-1,-1), Scalar(0,0,0)); | ||
overlay_values(outframe, minp+Point(1,1), Scalar(255,255,255)); | ||
overlay_values(outframe, minp, Scalar(255,0,0)); | ||
|
||
overlay_values(outframe, maxp+Point(-1,-1), Scalar(0,0,0)); | ||
overlay_values(outframe, maxp+Point(1,1), Scalar(255,255,255)); | ||
overlay_values(outframe, maxp, Scalar(0,0,255)); | ||
} | ||
|
||
int main(int argc, char** argv) | ||
|
@@ -140,7 +233,9 @@ int main(int argc, char** argv) | |
return -1; | ||
} | ||
|
||
process_frame(seekframe, outframe, scale, colormap, rotate); | ||
printf("WxH: %d %d\n", seekframe.cols, seekframe.rows); | ||
|
||
process_frame(seekframe, outframe, scale, colormap, rotate, seek->device_temp_sensor()); | ||
|
||
// Create an output object, if output specified then setup the pipeline unless output is set to 'window' | ||
VideoWriter writer; | ||
|
@@ -164,7 +259,7 @@ int main(int argc, char** argv) | |
} | ||
|
||
// Retrieve frame from seek and process | ||
process_frame(seekframe, outframe, scale, colormap, rotate); | ||
process_frame(seekframe, outframe, scale, colormap, rotate, seek->device_temp_sensor()); | ||
|
||
if (output == "window") { | ||
imshow("SeekThermal", outframe); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -184,6 +184,15 @@ bool SeekCam::open_cam() | |
return false; | ||
} | ||
|
||
void save_frame_img(cv::Mat &frame, int frameId) { | ||
cv::Mat dst; | ||
dst.create(frame.rows, frame.cols, frame.type()); | ||
//normalize(frame, dst, 0, 65535, cv::NORM_MINMAX); | ||
char outfile[256]; | ||
sprintf(outfile, "frame-%d.png", frameId); | ||
cv::imwrite(outfile, dst); | ||
} | ||
|
||
bool SeekCam::get_frame() | ||
{ | ||
/* request new frame */ | ||
|
@@ -197,6 +206,8 @@ bool SeekCam::get_frame() | |
if (!m_dev.fetch_frame(m_raw_data, m_raw_data_size)) | ||
return false; | ||
|
||
// save_frame_img(m_raw_frame, frame_id()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Left over debugging code? |
||
|
||
return true; | ||
} | ||
|
||
|
@@ -265,6 +276,7 @@ void SeekCam::create_dead_pixel_list(cv::Mat frame, cv::Mat& dead_pixel_mask, | |
} | ||
} | ||
} while (has_unlisted_pixels); | ||
printf("Found %lu dead pixels\n", dead_pixel_list.size()); | ||
} | ||
|
||
void SeekCam::apply_dead_pixel_filter(cv::Mat& src, cv::Mat& dst) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prefer FONT_HERSHEY_PLAIN, screen interfaces should use san-serif fonts.