restructure, start flask stuff
|
@ -2,7 +2,8 @@
|
|||
|
||||
.vscode/
|
||||
*.swp
|
||||
|
||||
uploads/*
|
||||
!uploads/.gitkeep
|
||||
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
|
|
3
Pipfile
|
@ -6,6 +6,9 @@ name = "pypi"
|
|||
[packages]
|
||||
opencv-python = "*"
|
||||
numba = "*"
|
||||
flask = "*"
|
||||
gunicorn = "*"
|
||||
werkzeug = "*"
|
||||
|
||||
[dev-packages]
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "4d38c8456723919069d64e7e19fd21317602969788feb71d5a4b4bbd183adcf2"
|
||||
"sha256": "f32b823e3975ed0083bf7bedff36887eb3c9a01fe41b0e9142630b508e63692a"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
|
@ -16,6 +16,46 @@
|
|||
]
|
||||
},
|
||||
"default": {
|
||||
"click": {
|
||||
"hashes": [
|
||||
"sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e",
|
||||
"sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==8.1.3"
|
||||
},
|
||||
"flask": {
|
||||
"hashes": [
|
||||
"sha256:642c450d19c4ad482f96729bd2a8f6d32554aa1e231f4f6b4e7e5264b16cca2b",
|
||||
"sha256:b9c46cc36662a7949f34b52d8ec7bb59c0d74ba08ba6cb9ce9adc1d8676d9526"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.2.2"
|
||||
},
|
||||
"gunicorn": {
|
||||
"hashes": [
|
||||
"sha256:9dcc4547dbb1cb284accfb15ab5667a0e5d1881cc443e0677b4882a4067a807e",
|
||||
"sha256:e0a968b5ba15f8a328fdfd7ab1fcb5af4470c28aaf7e55df02a99bc13138e6e8"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==20.1.0"
|
||||
},
|
||||
"itsdangerous": {
|
||||
"hashes": [
|
||||
"sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44",
|
||||
"sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==2.1.2"
|
||||
},
|
||||
"jinja2": {
|
||||
"hashes": [
|
||||
"sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852",
|
||||
"sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==3.1.2"
|
||||
},
|
||||
"llvmlite": {
|
||||
"hashes": [
|
||||
"sha256:03aee0ccd81735696474dc4f8b6be60774892a2929d6c05d093d17392c237f32",
|
||||
|
@ -50,6 +90,52 @@
|
|||
"markers": "python_version >= '3.7'",
|
||||
"version": "==0.39.1"
|
||||
},
|
||||
"markupsafe": {
|
||||
"hashes": [
|
||||
"sha256:0212a68688482dc52b2d45013df70d169f542b7394fc744c02a57374a4207003",
|
||||
"sha256:089cf3dbf0cd6c100f02945abeb18484bd1ee57a079aefd52cffd17fba910b88",
|
||||
"sha256:10c1bfff05d95783da83491be968e8fe789263689c02724e0c691933c52994f5",
|
||||
"sha256:33b74d289bd2f5e527beadcaa3f401e0df0a89927c1559c8566c066fa4248ab7",
|
||||
"sha256:3799351e2336dc91ea70b034983ee71cf2f9533cdff7c14c90ea126bfd95d65a",
|
||||
"sha256:3ce11ee3f23f79dbd06fb3d63e2f6af7b12db1d46932fe7bd8afa259a5996603",
|
||||
"sha256:421be9fbf0ffe9ffd7a378aafebbf6f4602d564d34be190fc19a193232fd12b1",
|
||||
"sha256:43093fb83d8343aac0b1baa75516da6092f58f41200907ef92448ecab8825135",
|
||||
"sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247",
|
||||
"sha256:4a33dea2b688b3190ee12bd7cfa29d39c9ed176bda40bfa11099a3ce5d3a7ac6",
|
||||
"sha256:4b9fe39a2ccc108a4accc2676e77da025ce383c108593d65cc909add5c3bd601",
|
||||
"sha256:56442863ed2b06d19c37f94d999035e15ee982988920e12a5b4ba29b62ad1f77",
|
||||
"sha256:671cd1187ed5e62818414afe79ed29da836dde67166a9fac6d435873c44fdd02",
|
||||
"sha256:694deca8d702d5db21ec83983ce0bb4b26a578e71fbdbd4fdcd387daa90e4d5e",
|
||||
"sha256:6a074d34ee7a5ce3effbc526b7083ec9731bb3cbf921bbe1d3005d4d2bdb3a63",
|
||||
"sha256:6d0072fea50feec76a4c418096652f2c3238eaa014b2f94aeb1d56a66b41403f",
|
||||
"sha256:6fbf47b5d3728c6aea2abb0589b5d30459e369baa772e0f37a0320185e87c980",
|
||||
"sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b",
|
||||
"sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812",
|
||||
"sha256:8dc1c72a69aa7e082593c4a203dcf94ddb74bb5c8a731e4e1eb68d031e8498ff",
|
||||
"sha256:8e3dcf21f367459434c18e71b2a9532d96547aef8a871872a5bd69a715c15f96",
|
||||
"sha256:8e576a51ad59e4bfaac456023a78f6b5e6e7651dcd383bcc3e18d06f9b55d6d1",
|
||||
"sha256:96e37a3dc86e80bf81758c152fe66dbf60ed5eca3d26305edf01892257049925",
|
||||
"sha256:97a68e6ada378df82bc9f16b800ab77cbf4b2fada0081794318520138c088e4a",
|
||||
"sha256:99a2a507ed3ac881b975a2976d59f38c19386d128e7a9a18b7df6fff1fd4c1d6",
|
||||
"sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e",
|
||||
"sha256:b09bf97215625a311f669476f44b8b318b075847b49316d3e28c08e41a7a573f",
|
||||
"sha256:b7bd98b796e2b6553da7225aeb61f447f80a1ca64f41d83612e6139ca5213aa4",
|
||||
"sha256:b87db4360013327109564f0e591bd2a3b318547bcef31b468a92ee504d07ae4f",
|
||||
"sha256:bcb3ed405ed3222f9904899563d6fc492ff75cce56cba05e32eff40e6acbeaa3",
|
||||
"sha256:d4306c36ca495956b6d568d276ac11fdd9c30a36f1b6eb928070dc5360b22e1c",
|
||||
"sha256:d5ee4f386140395a2c818d149221149c54849dfcfcb9f1debfe07a8b8bd63f9a",
|
||||
"sha256:dda30ba7e87fbbb7eab1ec9f58678558fd9a6b8b853530e176eabd064da81417",
|
||||
"sha256:e04e26803c9c3851c931eac40c695602c6295b8d432cbe78609649ad9bd2da8a",
|
||||
"sha256:e1c0b87e09fa55a220f058d1d49d3fb8df88fbfab58558f1198e08c1e1de842a",
|
||||
"sha256:e72591e9ecd94d7feb70c1cbd7be7b3ebea3f548870aa91e2732960fa4d57a37",
|
||||
"sha256:e8c843bbcda3a2f1e3c2ab25913c80a3c5376cd00c6e8c4a86a89a28c8dc5452",
|
||||
"sha256:efc1913fd2ca4f334418481c7e595c00aad186563bbc1ec76067848c7ca0a933",
|
||||
"sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a",
|
||||
"sha256:fc7b548b17d238737688817ab67deebb30e8073c95749d55538ed473130ec0c7"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==2.1.1"
|
||||
},
|
||||
"numba": {
|
||||
"hashes": [
|
||||
"sha256:0c358fd4ef7c5efc09ee96432284d66df285bd68654e85c39cf6c570dc35429a",
|
||||
|
@ -115,7 +201,7 @@
|
|||
"sha256:f8c02ec3c4c4fcb718fdf89a6c6f709b14949408e8cf2a2be5bfa9c49548fd85",
|
||||
"sha256:ffcf105ecdd9396e05a8e58e81faaaf34d3f9875f137c7372450baa5d77c9a54"
|
||||
],
|
||||
"markers": "python_version >= '3.10'",
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==1.23.3"
|
||||
},
|
||||
"opencv-python": {
|
||||
|
@ -138,6 +224,14 @@
|
|||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==59.8.0"
|
||||
},
|
||||
"werkzeug": {
|
||||
"hashes": [
|
||||
"sha256:7ea2d48322cc7c0f8b3a215ed73eabd7b5d75d0b50e31ab006286ccff9e00b8f",
|
||||
"sha256:f979ab81f58d7318e064e99c4506445d60135ac5cd2e177a2de0089bfd4c9bd5"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.2.2"
|
||||
}
|
||||
},
|
||||
"develop": {}
|
||||
|
|
|
@ -7,26 +7,6 @@
|
|||
<td class="legend-cell"><div style="width:20px;height:20px;background-color:rgb(256, 176, 0);"></div></td>
|
||||
<td class="legend-cell">0°C</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="legend-cell"><div style="width:20px;height:20px;background-color:rgb(168, 0, 0);"></div></td>
|
||||
<td class="legend-cell">800°C</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="legend-cell"><div style="width:20px;height:20px;background-color:rgb(0, 96, 255);"></div></td>
|
||||
<td class="legend-cell">900°C</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="legend-cell"><div style="width:20px;height:20px;background-color:rgb(106, 255, 150);"></div></td>
|
||||
<td class="legend-cell">1000°C</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="legend-cell"><div style="width:20px;height:20px;background-color:rgb(255, 136, 0);"></div></td>
|
||||
<td class="legend-cell">1000°C</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="legend-cell"><div style="width:20px;height:20px;background-color:rgb(128, 0, 0);"></div></td>
|
||||
<td class="legend-cell">1000°C</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<style>
|
||||
|
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 513 KiB After Width: | Height: | Size: 513 KiB |
Before Width: | Height: | Size: 986 KiB After Width: | Height: | Size: 986 KiB |
Before Width: | Height: | Size: 1.3 MiB After Width: | Height: | Size: 1.3 MiB |
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 9.9 KiB |
Before Width: | Height: | Size: 414 KiB After Width: | Height: | Size: 414 KiB |
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 7.7 KiB |
Before Width: | Height: | Size: 354 KiB After Width: | Height: | Size: 354 KiB |
Before Width: | Height: | Size: 841 KiB After Width: | Height: | Size: 841 KiB |
|
@ -0,0 +1,138 @@
|
|||
import math
|
||||
import cv2 as cv
|
||||
import numpy as np
|
||||
from numba import jit
|
||||
import json
|
||||
|
||||
# camera settings
|
||||
file = '01-0001.png'
|
||||
I_Darkcurrent = 150.5
|
||||
exposure_time = 0.500
|
||||
f_stop = 2.4
|
||||
ISO = 64 # basically brightness
|
||||
|
||||
# pyrometry config
|
||||
MAX_TEMP = 1200
|
||||
MIN_TEMP = 60
|
||||
# original range from paper
|
||||
# MAX_GR_RATIO = 1200
|
||||
# MIN_GR_RATIO = 600
|
||||
|
||||
# Cropping config
|
||||
x1 = 420
|
||||
x2 = 1200
|
||||
y1 = 400
|
||||
y2 = -1
|
||||
|
||||
# post-processing
|
||||
smoothing_radius = 2
|
||||
|
||||
# temperature key generation
|
||||
key_entries = 6
|
||||
|
||||
|
||||
@jit(nopython=True)
|
||||
def rg_ratio_normalize(imgarr):
|
||||
# set max & min to most extreme values,
|
||||
# work up & down respectively from there
|
||||
tmin = MAX_TEMP
|
||||
tmax = 0
|
||||
|
||||
imgnew = imgarr
|
||||
for i in range(len(imgarr)):
|
||||
for j in range(len(imgarr[i])):
|
||||
px = imgarr[i][j]
|
||||
r_norm = normalization_func(px[0])
|
||||
g_norm = normalization_func(px[1])
|
||||
|
||||
# apply camera calibration func
|
||||
temp_C = pyrometry_calibration_formula(g_norm, r_norm)
|
||||
|
||||
# remove pixels outside calibration range
|
||||
if MAX_TEMP != None and temp_C > MAX_TEMP or MIN_TEMP != None and temp_C < MIN_TEMP:
|
||||
temp_C = 0
|
||||
|
||||
# update min & max
|
||||
if temp_C < tmin and temp_C >= 0:
|
||||
tmin = temp_C
|
||||
if temp_C > tmax:
|
||||
tmax = temp_C
|
||||
|
||||
imgnew[i][j] = [temp_C, temp_C, temp_C]
|
||||
return imgnew, tmin, tmax
|
||||
|
||||
|
||||
@jit(nopython=True)
|
||||
def normalization_func(i):
|
||||
"""
|
||||
does something to the pixels that i don't understand lol
|
||||
"""
|
||||
return (i - I_Darkcurrent) * (f_stop ** 2) / (ISO * exposure_time)
|
||||
|
||||
|
||||
@jit(nopython=True)
|
||||
def pyrometry_calibration_formula(i_ng, i_nr):
|
||||
"""
|
||||
Given the green-red ratio, calculates an approximate temperature
|
||||
in Celsius.
|
||||
"""
|
||||
return 362.73 * math.log10(
|
||||
(i_ng/i_nr) ** 3
|
||||
) + 2186.7 * math.log10(
|
||||
(i_ng/i_nr) ** 3
|
||||
) + 4466.5 * math.log10(
|
||||
(i_ng / i_nr) ** 3
|
||||
) + 3753.5
|
||||
|
||||
|
||||
# read image & crop
|
||||
file_name = file.split(".")[0]
|
||||
file_ext = file.split(".")[1]
|
||||
img = cv.imread(file)
|
||||
img = img[y1:y2, x1:x2]
|
||||
cv.imwrite(f'{file_name}-cropped.{file_ext}', img)
|
||||
|
||||
# img = cv.imread('ember_test.png')
|
||||
|
||||
img, tmin, tmax = rg_ratio_normalize(img)
|
||||
|
||||
print(f"min: {tmin}°C")
|
||||
print(f"max: {tmax}°C")
|
||||
|
||||
# build & apply smoothing conv kernel
|
||||
k = []
|
||||
for i in range(smoothing_radius):
|
||||
k.append([1/(smoothing_radius**2) for i in range(smoothing_radius)])
|
||||
kernel = np.array(k)
|
||||
|
||||
img = cv.filter2D(src=img, ddepth=-1, kernel=kernel)
|
||||
|
||||
# write colormapped image
|
||||
img_jet = cv.applyColorMap(img, cv.COLORMAP_JET)
|
||||
cv.imwrite(f'{file_name}-cropped-transformed-ratio.{file_ext}', img_jet)
|
||||
|
||||
# --- Generate temperature key ---
|
||||
|
||||
# adjust max & min temps to be the same as the image
|
||||
# tmin_adj = tmin / (smoothing_radius ** 2)
|
||||
# tmax_adj = tmax / (smoothing_radius ** 2)
|
||||
# Generate 6-step key
|
||||
step = (tmax - tmin) / (key_entries-1)
|
||||
temps = []
|
||||
key_img_arr = [[]]
|
||||
for i in range(key_entries):
|
||||
res_temp = tmin + (i * step)
|
||||
res_color = (tmax - (i * step)) / MAX_TEMP * 255
|
||||
temps.append(res_temp)
|
||||
key_img_arr[0].append([res_color, res_color, res_color])
|
||||
|
||||
key_img = np.array(key_img_arr).astype(np.uint8)
|
||||
key_img_jet = cv.applyColorMap(key_img, cv.COLORMAP_JET)
|
||||
# cv.imwrite(f'{file_name}-key.{file_ext}', key_img_jet)
|
||||
|
||||
tempkey = {}
|
||||
for i in range(len(temps)):
|
||||
c = key_img_jet[0][i]
|
||||
tempkey[temps[i]] = f"rgb({c[0]}, {c[1]}, {c[2]})"
|
||||
|
||||
print(json.dumps(tempkey, indent=4))
|
|
@ -0,0 +1,16 @@
|
|||
from flask import Flask, render_template, request
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route('/', methods=['GET'])
|
||||
def index():
|
||||
return render_template('index.html')
|
||||
|
||||
@app.route('/ratio_pyro', methods=['POST'])
|
||||
def ratio_pyro():
|
||||
f = request.files['file']
|
||||
I_Darkcurrent = 150.5
|
||||
exposure_time = 0.500
|
||||
f_stop = 2.4
|
||||
ISO = 64
|
||||
return 200
|
|
@ -84,6 +84,7 @@ def pyrometry_calibration_formula(i_ng, i_nr):
|
|||
(i_ng / i_nr) ** 3
|
||||
) + 3753.5
|
||||
|
||||
def ratio_pyrometry_pipeline(file):
|
||||
|
||||
# read image & crop
|
||||
file_name = file.split(".")[0]
|
||||
|
@ -96,9 +97,6 @@ cv.imwrite(f'{file_name}-cropped.{file_ext}', img)
|
|||
|
||||
img, tmin, tmax = rg_ratio_normalize(img)
|
||||
|
||||
print(f"min: {tmin}°C")
|
||||
print(f"max: {tmax}°C")
|
||||
|
||||
# build & apply smoothing conv kernel
|
||||
k = []
|
||||
for i in range(smoothing_radius):
|
||||
|
@ -128,14 +126,8 @@ for i in range(key_entries):
|
|||
|
||||
key_img = np.array(key_img_arr).astype(np.uint8)
|
||||
key_img_jet = cv.applyColorMap(key_img, cv.COLORMAP_JET)
|
||||
# cv.imwrite(f'{file_name}-key.{file_ext}', key_img_jet)
|
||||
|
||||
tempkey = {}
|
||||
for i in range(len(temps)):
|
||||
c = key_img_jet[0][i]
|
||||
tempkey[temps[i]] = f"rgb({c[0]}, {c[1]}, {c[2]})"
|
||||
|
||||
# with open(f"{file_name}-tempkey.json", "w+") as file_out:
|
||||
# json.dump(tempkey, file_out)
|
||||
|
||||
print(json.dumps(tempkey, indent=4))
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
.form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
<!DOCTYPE html>
|
||||
<head>
|
||||
<title>Pyrometry Application</title>
|
||||
<link rel="app.css">
|
||||
</head>
|
||||
<body>
|
||||
{% block content %}
|
||||
</body>
|
|
@ -0,0 +1,7 @@
|
|||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
<div class="form">
|
||||
<button onclick="">
|
||||
</button>
|
||||
</div>
|
||||
{% endblock %}
|