fluke-thermal-reader 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. fluke_thermal_reader-0.1.0/MANIFEST.in +5 -0
  2. fluke_thermal_reader-0.1.0/PKG-INFO +318 -0
  3. fluke_thermal_reader-0.1.0/README.md +285 -0
  4. fluke_thermal_reader-0.1.0/examples/basic_usage.py +96 -0
  5. fluke_thermal_reader-0.1.0/examples/batch_processing.py +188 -0
  6. fluke_thermal_reader-0.1.0/examples/readis2.py +36 -0
  7. fluke_thermal_reader-0.1.0/examples/simple_usage.py +82 -0
  8. fluke_thermal_reader-0.1.0/fluke_thermal_reader/__init__.py +35 -0
  9. fluke_thermal_reader-0.1.0/fluke_thermal_reader/cli.py +114 -0
  10. fluke_thermal_reader-0.1.0/fluke_thermal_reader/models.py +57 -0
  11. fluke_thermal_reader-0.1.0/fluke_thermal_reader/parsers.py +374 -0
  12. fluke_thermal_reader-0.1.0/fluke_thermal_reader/reader.py +177 -0
  13. fluke_thermal_reader-0.1.0/fluke_thermal_reader.egg-info/PKG-INFO +318 -0
  14. fluke_thermal_reader-0.1.0/fluke_thermal_reader.egg-info/SOURCES.txt +25 -0
  15. fluke_thermal_reader-0.1.0/fluke_thermal_reader.egg-info/dependency_links.txt +1 -0
  16. fluke_thermal_reader-0.1.0/fluke_thermal_reader.egg-info/requires.txt +12 -0
  17. fluke_thermal_reader-0.1.0/fluke_thermal_reader.egg-info/top_level.txt +1 -0
  18. fluke_thermal_reader-0.1.0/pyproject.toml +62 -0
  19. fluke_thermal_reader-0.1.0/requirements.txt +1 -0
  20. fluke_thermal_reader-0.1.0/setup.cfg +4 -0
  21. fluke_thermal_reader-0.1.0/test/test_all_parameters.py +289 -0
  22. fluke_thermal_reader-0.1.0/test/test_emissivity_differences.py +240 -0
  23. fluke_thermal_reader-0.1.0/test/test_fluke_reader.py +101 -0
  24. fluke_thermal_reader-0.1.0/test/test_gh_file.py +64 -0
  25. fluke_thermal_reader-0.1.0/test/test_transmission.py +305 -0
  26. fluke_thermal_reader-0.1.0/tests/__init__.py +2 -0
  27. fluke_thermal_reader-0.1.0/tests/test_reader.py +127 -0
@@ -0,0 +1,5 @@
1
+ include README.md
2
+ include requirements.txt
3
+ recursive-include examples *.py
4
+ recursive-include tests *.py
5
+
@@ -0,0 +1,318 @@
1
+ Metadata-Version: 2.4
2
+ Name: fluke_thermal_reader
3
+ Version: 0.1.0
4
+ Summary: Libreria Python per leggere file termografici Fluke (.is2 e .is3)
5
+ Author-email: Lorenzo Ghidini <lorigh46@gmail.com>
6
+ Project-URL: Homepage, https://github.com/LoriGH25/FlukeReader_Python
7
+ Project-URL: Repository, https://github.com/LoriGH25/FlukeReader_Python
8
+ Project-URL: Issues, https://github.com/LoriGH25/FlukeReader_Python/issues
9
+ Keywords: fluke,thermal,thermography,is2,is3,temperature
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Science/Research
12
+ Classifier: Operating System :: OS Independent
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.8
15
+ Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Topic :: Scientific/Engineering :: Physics
20
+ Classifier: Topic :: Scientific/Engineering :: Image Processing
21
+ Requires-Python: >=3.8
22
+ Description-Content-Type: text/markdown
23
+ Requires-Dist: numpy>=1.20.0
24
+ Provides-Extra: dev
25
+ Requires-Dist: pytest>=6.0; extra == "dev"
26
+ Requires-Dist: pytest-cov; extra == "dev"
27
+ Requires-Dist: black; extra == "dev"
28
+ Requires-Dist: flake8; extra == "dev"
29
+ Requires-Dist: mypy; extra == "dev"
30
+ Provides-Extra: docs
31
+ Requires-Dist: sphinx; extra == "docs"
32
+ Requires-Dist: sphinx-rtd-theme; extra == "docs"
33
+
34
+ # Fluke Thermal Reader
35
+
36
+ A Python library for reading and analyzing Fluke thermal files (.is2 and .is3 formats).
37
+
38
+ **Package**: `fluke_thermal_reader` | **Import**: `import fluke_thermal_reader`
39
+
40
+ ## Features
41
+
42
+ - **Complete .is2 support**: Parse Fluke .is2 thermal imaging files
43
+ - **Accurate temperature conversion**: Convert raw thermal data to temperature values with high precision
44
+ - **Metadata extraction**: Extract camera information, calibration data, and image properties
45
+ - **Fusion offset correction**: Automatic correction for horizontal shift in thermal images
46
+ - **Lightweight design**: Minimal dependencies (only numpy required)
47
+ - **Optional image loading**: Images are returned as paths, not loaded automatically
48
+ - **Tested camera models**: Ti300 and Ti480P (other models supported with user feedback)
49
+
50
+ ## Installation
51
+
52
+ ```bash
53
+ pip install fluke_thermal_reader
54
+ ```
55
+
56
+ **Important**: package name and import are identical: `fluke_thermal_reader`.
57
+
58
+ ## Quick Start
59
+
60
+ ```python
61
+ from fluke_thermal_reader import read_is2
62
+
63
+ # Load a Fluke .is2 file
64
+ data = read_is2("thermal_image.is2")
65
+
66
+ # Access thermal data
67
+ thermal_data = data['data'] # 2D numpy array of temperatures
68
+ print(f"Temperature range: {thermal_data.min():.1f}°C - {thermal_data.max():.1f}°C")
69
+
70
+ # Access metadata
71
+ print(f"Camera: {data['CameraModel']}")
72
+ print(f"Image size: {data['size']}")
73
+ print(f"Emissivity: {data['Emissivity']}")
74
+ print(f"Background temperature: {data['BackgroundTemp']}°C")
75
+ ```
76
+
77
+ ## Supported File Formats
78
+
79
+ - **IS2 (images)**: Fluke thermal image format — FULLY SUPPORTED
80
+ - **IS3 (video)**: Fluke thermal video format — FUTURE WORK (not implemented yet)
81
+
82
+ All the examples and usage below refer to IS2 image files only.
83
+
84
+ ## Image Handling
85
+
86
+ The library is designed to be lightweight and efficient. Images (thumbnails and visible photos) are handled as follows:
87
+
88
+ - **Paths only**: Images are returned as file paths, not loaded automatically
89
+ - **Optional loading**: You choose when and how to load images
90
+ - **Memory efficient**: No automatic image loading saves memory
91
+ - **Flexible**: Use any image library you prefer (matplotlib, PIL, opencv, etc.)
92
+
93
+ ```python
94
+ # Images are returned as paths
95
+ data = read_is2("thermal_image.is2")
96
+ print(f"Thumbnail path: {data['thumbnail_path']}")
97
+ print(f"Photo path: {data['photo_path']}")
98
+
99
+ # Load images only when needed
100
+ if data['thumbnail_path']:
101
+ # Option 1: Using matplotlib
102
+ import matplotlib.pyplot as plt
103
+ thumbnail = plt.imread(data['thumbnail_path'])
104
+
105
+ # Option 2: Using PIL (lighter)
106
+ from PIL import Image
107
+ thumbnail = Image.open(data['thumbnail_path'])
108
+ ```
109
+
110
+ ## Tested Camera Models
111
+
112
+ - **Ti300**: Fully tested and supported
113
+ - **Ti480P**: Fully tested and supported
114
+
115
+ **Other Fluke camera models**: If you have files from other Fluke thermal cameras, please share them so we can add support for additional models.
116
+
117
+ ## API Reference
118
+
119
+ ### `read_is2(file_path)`
120
+
121
+ Load and parse a Fluke thermal .is2 file.
122
+
123
+ **Parameters:**
124
+ - `file_path` (str): Path to the .is2 file
125
+
126
+ **Returns:**
127
+ - `dict`: Dictionary containing thermal data and metadata
128
+
129
+
130
+ **Returned Data Structure (read_is2):**
131
+ ```python
132
+ {
133
+ 'data': numpy.ndarray, # 2D array of temperature values
134
+ 'FileName': str, # Original filename
135
+ 'CameraModel': str, # Camera model
136
+ 'CameraSerial': str, # Camera serial number
137
+ 'size': [width, height], # Image dimensions
138
+ 'MinTemp': float, # Minimum temperature
139
+ 'MaxTemp': float, # Maximum temperature
140
+ 'AvgTemp': float, # Average temperature
141
+ 'Emissivity': float, # Emissivity setting
142
+ 'BackgroundTemp': float, # Background temperature
143
+ 'CaptureDateTime': str, # Capture date and time
144
+ 'thumbnail_path': str, # Path to thumbnail image (if available)
145
+ 'photo_path': str, # Path to visible light image (if available)
146
+ }
147
+ ```
148
+
149
+ ## Examples
150
+
151
+ ### Simple Usage (No External Dependencies)
152
+
153
+ ```python
154
+ from fluke_thermal_reader import read_is2
155
+ import numpy as np
156
+
157
+ # Load thermal data
158
+ data = read_is2("thermal_image.is2")
159
+
160
+ # Basic analysis
161
+ temperatures = data['data']
162
+ print(f"Temperature range: {temperatures.min():.1f}°C - {temperatures.max():.1f}°C")
163
+ print(f"Average: {temperatures.mean():.1f}°C")
164
+
165
+ # Hot spot analysis
166
+ hot_spots = temperatures > (temperatures.mean() + 2 * temperatures.std())
167
+ print(f"Hot spots: {np.sum(hot_spots)} pixels")
168
+ ```
169
+
170
+ ### Basic Usage (With Visualization)
171
+
172
+ ```python
173
+ from fluke_thermal_reader import read_is2
174
+ import matplotlib.pyplot as plt
175
+
176
+ # Load thermal data
177
+ data = read_is2("thermal_image.is2")
178
+
179
+ # Display thermal image
180
+ plt.imshow(data['data'], cmap='hot')
181
+ plt.colorbar(label='Temperature (°C)')
182
+ plt.title(f'Thermal Image - {data["CameraModel"]}')
183
+ plt.show()
184
+
185
+ # Load images separately if needed (optional)
186
+ if data['thumbnail_path']:
187
+ # Using matplotlib (requires matplotlib)
188
+ thumbnail = plt.imread(data['thumbnail_path'])
189
+ plt.figure()
190
+ plt.imshow(thumbnail)
191
+ plt.title('Thumbnail')
192
+ plt.show()
193
+
194
+ # Or using PIL (lighter alternative)
195
+ # from PIL import Image
196
+ # thumbnail = Image.open(data['thumbnail_path'])
197
+ # thumbnail.show()
198
+ ```
199
+
200
+ ### Batch Processing
201
+
202
+ ```python
203
+ import os
204
+ from fluke_thermal_reader import read_is2
205
+
206
+ # Process multiple files
207
+ for filename in os.listdir("thermal_images/"):
208
+ if filename.endswith(".is2"):
209
+ data = read_is2(f"thermal_images/{filename}")
210
+ print(f"Processed {filename}: {data['MinTemp']:.1f}°C - {data['MaxTemp']:.1f}°C")
211
+ ```
212
+
213
+ ### Temperature Analysis
214
+
215
+ ```python
216
+ import numpy as np
217
+ from fluke_thermal_reader import read_is2
218
+
219
+ # Load data
220
+ data = read_is2("thermal_image.is2")
221
+ temperatures = data['data']
222
+
223
+ # Statistical analysis
224
+ print(f"Temperature statistics:")
225
+ print(f" Mean: {temperatures.mean():.1f}°C")
226
+ print(f" Std: {temperatures.std():.1f}°C")
227
+ print(f" Min: {temperatures.min():.1f}°C")
228
+ print(f" Max: {temperatures.max():.1f}°C")
229
+
230
+ # Find hot spots
231
+ hot_spots = temperatures > (temperatures.mean() + 2 * temperatures.std())
232
+ print(f"Hot spots: {np.sum(hot_spots)} pixels")
233
+ ```
234
+
235
+ ## Accuracy
236
+
237
+ The library provides highly accurate temperature readings with:
238
+ - **Mean difference**: < 0.5°C compared to Fluke's official software
239
+ - **Correlation**: > 0.999 with reference data
240
+ - **Precision**: 16 decimal places for temperature values
241
+ - **Tested on**: Ti300 and Ti480P cameras with real-world data
242
+
243
+ ## Requirements
244
+
245
+ - Python 3.8+
246
+ - numpy>=1.20.0
247
+
248
+ **Optional dependencies for visualization:**
249
+ - matplotlib (for plotting thermal data)
250
+ - PIL/Pillow (for loading images)
251
+
252
+ ## Development
253
+
254
+ ### Project Structure
255
+
256
+ ```
257
+ fluke_reader/
258
+ ├── fluke_reader/ # Main library code
259
+ │ ├── __init__.py
260
+ │ ├── parsers.py # File parsers
261
+ │ ├── reader.py # Main reader functions
262
+ │ └── models.py # Data models
263
+ ├── examples/ # Usage examples
264
+ ├── test/ # Test files and analysis scripts
265
+ ├── legacy/ # Legacy code and references
266
+ └── README.md
267
+ ```
268
+
269
+ ### Running Tests
270
+
271
+ ```bash
272
+ # Run basic tests
273
+ python -m pytest
274
+
275
+ # Run with coverage
276
+ python -m pytest --cov=fluke_thermal_reader
277
+ ```
278
+
279
+ ## Contributing
280
+
281
+ Contributions are welcome! Please feel free to submit a Pull Request.
282
+
283
+ **Adding support for new camera models**: If you have .is2 files from other Fluke thermal cameras, please share them so we can extend support to additional models. You can:
284
+ - Open an issue with sample files
285
+ - Submit a pull request with test data
286
+ - Contact the maintainers directly
287
+
288
+ ## License
289
+
290
+ This project is licensed under the MIT License - see the LICENSE file for details.
291
+
292
+ ## Acknowledgments
293
+
294
+ - Fluke Corporation for the thermal imaging technology
295
+ - The open-source community for inspiration and tools
296
+
297
+ ## Changelog
298
+
299
+ ### Version 1.0.0
300
+ - Initial release
301
+ - Full .is2 support
302
+ - Accurate temperature conversion (< 0.5°C difference from Fluke software)
303
+ - Metadata extraction
304
+ - Fusion offset correction
305
+ - Support for Ti300 and Ti480P cameras
306
+ - Ready for additional camera model support with user feedback
307
+
308
+ ---
309
+
310
+ ## read_is3 (Future Work)
311
+
312
+ `read_is3(file_path)` is planned for Fluke IS3 (video) files.
313
+
314
+ - Current status: Not implemented — calling it raises `NotImplementedError`.
315
+ - Scope: video streams (multiple thermal frames), video-level metadata.
316
+ - Documentation: the returned data structure will be defined once implementation starts.
317
+
318
+ If you are interested in IS3 support, please open an issue with sample files and requirements.
@@ -0,0 +1,285 @@
1
+ # Fluke Thermal Reader
2
+
3
+ A Python library for reading and analyzing Fluke thermal files (.is2 and .is3 formats).
4
+
5
+ **Package**: `fluke_thermal_reader` | **Import**: `import fluke_thermal_reader`
6
+
7
+ ## Features
8
+
9
+ - **Complete .is2 support**: Parse Fluke .is2 thermal imaging files
10
+ - **Accurate temperature conversion**: Convert raw thermal data to temperature values with high precision
11
+ - **Metadata extraction**: Extract camera information, calibration data, and image properties
12
+ - **Fusion offset correction**: Automatic correction for horizontal shift in thermal images
13
+ - **Lightweight design**: Minimal dependencies (only numpy required)
14
+ - **Optional image loading**: Images are returned as paths, not loaded automatically
15
+ - **Tested camera models**: Ti300 and Ti480P (other models supported with user feedback)
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ pip install fluke_thermal_reader
21
+ ```
22
+
23
+ **Important**: package name and import are identical: `fluke_thermal_reader`.
24
+
25
+ ## Quick Start
26
+
27
+ ```python
28
+ from fluke_thermal_reader import read_is2
29
+
30
+ # Load a Fluke .is2 file
31
+ data = read_is2("thermal_image.is2")
32
+
33
+ # Access thermal data
34
+ thermal_data = data['data'] # 2D numpy array of temperatures
35
+ print(f"Temperature range: {thermal_data.min():.1f}°C - {thermal_data.max():.1f}°C")
36
+
37
+ # Access metadata
38
+ print(f"Camera: {data['CameraModel']}")
39
+ print(f"Image size: {data['size']}")
40
+ print(f"Emissivity: {data['Emissivity']}")
41
+ print(f"Background temperature: {data['BackgroundTemp']}°C")
42
+ ```
43
+
44
+ ## Supported File Formats
45
+
46
+ - **IS2 (images)**: Fluke thermal image format — FULLY SUPPORTED
47
+ - **IS3 (video)**: Fluke thermal video format — FUTURE WORK (not implemented yet)
48
+
49
+ All the examples and usage below refer to IS2 image files only.
50
+
51
+ ## Image Handling
52
+
53
+ The library is designed to be lightweight and efficient. Images (thumbnails and visible photos) are handled as follows:
54
+
55
+ - **Paths only**: Images are returned as file paths, not loaded automatically
56
+ - **Optional loading**: You choose when and how to load images
57
+ - **Memory efficient**: No automatic image loading saves memory
58
+ - **Flexible**: Use any image library you prefer (matplotlib, PIL, opencv, etc.)
59
+
60
+ ```python
61
+ # Images are returned as paths
62
+ data = read_is2("thermal_image.is2")
63
+ print(f"Thumbnail path: {data['thumbnail_path']}")
64
+ print(f"Photo path: {data['photo_path']}")
65
+
66
+ # Load images only when needed
67
+ if data['thumbnail_path']:
68
+ # Option 1: Using matplotlib
69
+ import matplotlib.pyplot as plt
70
+ thumbnail = plt.imread(data['thumbnail_path'])
71
+
72
+ # Option 2: Using PIL (lighter)
73
+ from PIL import Image
74
+ thumbnail = Image.open(data['thumbnail_path'])
75
+ ```
76
+
77
+ ## Tested Camera Models
78
+
79
+ - **Ti300**: Fully tested and supported
80
+ - **Ti480P**: Fully tested and supported
81
+
82
+ **Other Fluke camera models**: If you have files from other Fluke thermal cameras, please share them so we can add support for additional models.
83
+
84
+ ## API Reference
85
+
86
+ ### `read_is2(file_path)`
87
+
88
+ Load and parse a Fluke thermal .is2 file.
89
+
90
+ **Parameters:**
91
+ - `file_path` (str): Path to the .is2 file
92
+
93
+ **Returns:**
94
+ - `dict`: Dictionary containing thermal data and metadata
95
+
96
+
97
+ **Returned Data Structure (read_is2):**
98
+ ```python
99
+ {
100
+ 'data': numpy.ndarray, # 2D array of temperature values
101
+ 'FileName': str, # Original filename
102
+ 'CameraModel': str, # Camera model
103
+ 'CameraSerial': str, # Camera serial number
104
+ 'size': [width, height], # Image dimensions
105
+ 'MinTemp': float, # Minimum temperature
106
+ 'MaxTemp': float, # Maximum temperature
107
+ 'AvgTemp': float, # Average temperature
108
+ 'Emissivity': float, # Emissivity setting
109
+ 'BackgroundTemp': float, # Background temperature
110
+ 'CaptureDateTime': str, # Capture date and time
111
+ 'thumbnail_path': str, # Path to thumbnail image (if available)
112
+ 'photo_path': str, # Path to visible light image (if available)
113
+ }
114
+ ```
115
+
116
+ ## Examples
117
+
118
+ ### Simple Usage (No External Dependencies)
119
+
120
+ ```python
121
+ from fluke_thermal_reader import read_is2
122
+ import numpy as np
123
+
124
+ # Load thermal data
125
+ data = read_is2("thermal_image.is2")
126
+
127
+ # Basic analysis
128
+ temperatures = data['data']
129
+ print(f"Temperature range: {temperatures.min():.1f}°C - {temperatures.max():.1f}°C")
130
+ print(f"Average: {temperatures.mean():.1f}°C")
131
+
132
+ # Hot spot analysis
133
+ hot_spots = temperatures > (temperatures.mean() + 2 * temperatures.std())
134
+ print(f"Hot spots: {np.sum(hot_spots)} pixels")
135
+ ```
136
+
137
+ ### Basic Usage (With Visualization)
138
+
139
+ ```python
140
+ from fluke_thermal_reader import read_is2
141
+ import matplotlib.pyplot as plt
142
+
143
+ # Load thermal data
144
+ data = read_is2("thermal_image.is2")
145
+
146
+ # Display thermal image
147
+ plt.imshow(data['data'], cmap='hot')
148
+ plt.colorbar(label='Temperature (°C)')
149
+ plt.title(f'Thermal Image - {data["CameraModel"]}')
150
+ plt.show()
151
+
152
+ # Load images separately if needed (optional)
153
+ if data['thumbnail_path']:
154
+ # Using matplotlib (requires matplotlib)
155
+ thumbnail = plt.imread(data['thumbnail_path'])
156
+ plt.figure()
157
+ plt.imshow(thumbnail)
158
+ plt.title('Thumbnail')
159
+ plt.show()
160
+
161
+ # Or using PIL (lighter alternative)
162
+ # from PIL import Image
163
+ # thumbnail = Image.open(data['thumbnail_path'])
164
+ # thumbnail.show()
165
+ ```
166
+
167
+ ### Batch Processing
168
+
169
+ ```python
170
+ import os
171
+ from fluke_thermal_reader import read_is2
172
+
173
+ # Process multiple files
174
+ for filename in os.listdir("thermal_images/"):
175
+ if filename.endswith(".is2"):
176
+ data = read_is2(f"thermal_images/{filename}")
177
+ print(f"Processed {filename}: {data['MinTemp']:.1f}°C - {data['MaxTemp']:.1f}°C")
178
+ ```
179
+
180
+ ### Temperature Analysis
181
+
182
+ ```python
183
+ import numpy as np
184
+ from fluke_thermal_reader import read_is2
185
+
186
+ # Load data
187
+ data = read_is2("thermal_image.is2")
188
+ temperatures = data['data']
189
+
190
+ # Statistical analysis
191
+ print(f"Temperature statistics:")
192
+ print(f" Mean: {temperatures.mean():.1f}°C")
193
+ print(f" Std: {temperatures.std():.1f}°C")
194
+ print(f" Min: {temperatures.min():.1f}°C")
195
+ print(f" Max: {temperatures.max():.1f}°C")
196
+
197
+ # Find hot spots
198
+ hot_spots = temperatures > (temperatures.mean() + 2 * temperatures.std())
199
+ print(f"Hot spots: {np.sum(hot_spots)} pixels")
200
+ ```
201
+
202
+ ## Accuracy
203
+
204
+ The library provides highly accurate temperature readings with:
205
+ - **Mean difference**: < 0.5°C compared to Fluke's official software
206
+ - **Correlation**: > 0.999 with reference data
207
+ - **Precision**: 16 decimal places for temperature values
208
+ - **Tested on**: Ti300 and Ti480P cameras with real-world data
209
+
210
+ ## Requirements
211
+
212
+ - Python 3.8+
213
+ - numpy>=1.20.0
214
+
215
+ **Optional dependencies for visualization:**
216
+ - matplotlib (for plotting thermal data)
217
+ - PIL/Pillow (for loading images)
218
+
219
+ ## Development
220
+
221
+ ### Project Structure
222
+
223
+ ```
224
+ fluke_reader/
225
+ ├── fluke_reader/ # Main library code
226
+ │ ├── __init__.py
227
+ │ ├── parsers.py # File parsers
228
+ │ ├── reader.py # Main reader functions
229
+ │ └── models.py # Data models
230
+ ├── examples/ # Usage examples
231
+ ├── test/ # Test files and analysis scripts
232
+ ├── legacy/ # Legacy code and references
233
+ └── README.md
234
+ ```
235
+
236
+ ### Running Tests
237
+
238
+ ```bash
239
+ # Run basic tests
240
+ python -m pytest
241
+
242
+ # Run with coverage
243
+ python -m pytest --cov=fluke_thermal_reader
244
+ ```
245
+
246
+ ## Contributing
247
+
248
+ Contributions are welcome! Please feel free to submit a Pull Request.
249
+
250
+ **Adding support for new camera models**: If you have .is2 files from other Fluke thermal cameras, please share them so we can extend support to additional models. You can:
251
+ - Open an issue with sample files
252
+ - Submit a pull request with test data
253
+ - Contact the maintainers directly
254
+
255
+ ## License
256
+
257
+ This project is licensed under the MIT License - see the LICENSE file for details.
258
+
259
+ ## Acknowledgments
260
+
261
+ - Fluke Corporation for the thermal imaging technology
262
+ - The open-source community for inspiration and tools
263
+
264
+ ## Changelog
265
+
266
+ ### Version 1.0.0
267
+ - Initial release
268
+ - Full .is2 support
269
+ - Accurate temperature conversion (< 0.5°C difference from Fluke software)
270
+ - Metadata extraction
271
+ - Fusion offset correction
272
+ - Support for Ti300 and Ti480P cameras
273
+ - Ready for additional camera model support with user feedback
274
+
275
+ ---
276
+
277
+ ## read_is3 (Future Work)
278
+
279
+ `read_is3(file_path)` is planned for Fluke IS3 (video) files.
280
+
281
+ - Current status: Not implemented — calling it raises `NotImplementedError`.
282
+ - Scope: video streams (multiple thermal frames), video-level metadata.
283
+ - Documentation: the returned data structure will be defined once implementation starts.
284
+
285
+ If you are interested in IS3 support, please open an issue with sample files and requirements.
@@ -0,0 +1,96 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Basic usage example for fluke_reader library.
4
+ """
5
+
6
+ from fluke_thermal_reader import read_is2
7
+ import numpy as np
8
+
9
+ # Optional: matplotlib for visualization (install with: pip install matplotlib)
10
+ try:
11
+ import matplotlib.pyplot as plt
12
+ HAS_MATPLOTLIB = True
13
+ except ImportError:
14
+ HAS_MATPLOTLIB = False
15
+ print("Note: matplotlib not available. Install with: pip install matplotlib")
16
+
17
+ def main():
18
+ """Basic usage example."""
19
+
20
+ # Example file path (replace with your actual file)
21
+ file_path = "thermal_image.is2"
22
+
23
+ try:
24
+ # Load thermal data
25
+ print(f"Loading thermal data from {file_path}...")
26
+ data = read_is2(file_path)
27
+
28
+ # Display basic information
29
+ print(f"\n=== THERMAL IMAGE INFORMATION ===")
30
+ print(f"File: {data['FileName']}")
31
+ print(f"Camera: {data['CameraModel']} (Serial: {data['CameraSerial']})")
32
+ print(f"Image size: {data['size'][0]}x{data['size'][1]} pixels")
33
+ print(f"Capture date: {data['CaptureDateTime']}")
34
+
35
+ # Temperature information
36
+ temperatures = data['data']
37
+ print(f"\n=== TEMPERATURE INFORMATION ===")
38
+ print(f"Temperature range: {temperatures.min():.1f}°C - {temperatures.max():.1f}°C")
39
+ print(f"Average temperature: {temperatures.mean():.1f}°C")
40
+ print(f"Standard deviation: {temperatures.std():.1f}°C")
41
+
42
+ # Camera settings
43
+ print(f"\n=== CAMERA SETTINGS ===")
44
+ print(f"Emissivity: {data['Emissivity']}")
45
+ print(f"Background temperature: {data['BackgroundTemp']}°C")
46
+
47
+ # Display thermal image (if matplotlib is available)
48
+ if HAS_MATPLOTLIB:
49
+ plt.figure(figsize=(12, 8))
50
+
51
+ # Thermal image
52
+ plt.subplot(1, 2, 1)
53
+ im1 = plt.imshow(temperatures, cmap='hot', aspect='auto')
54
+ plt.title('Thermal Image')
55
+ plt.xlabel('X (pixels)')
56
+ plt.ylabel('Y (pixels)')
57
+ plt.colorbar(im1, label='Temperature (°C)')
58
+
59
+ # Temperature histogram
60
+ plt.subplot(1, 2, 2)
61
+ plt.hist(temperatures.flatten(), bins=50, alpha=0.7, edgecolor='black')
62
+ plt.title('Temperature Distribution')
63
+ plt.xlabel('Temperature (°C)')
64
+ plt.ylabel('Frequency')
65
+ plt.axvline(temperatures.mean(), color='red', linestyle='--',
66
+ label=f'Mean: {temperatures.mean():.1f}°C')
67
+ plt.legend()
68
+
69
+ plt.tight_layout()
70
+ plt.show()
71
+ else:
72
+ print("\n=== VISUALIZATION ===")
73
+ print("Install matplotlib to see thermal image visualization:")
74
+ print("pip install matplotlib")
75
+
76
+ # Find hot spots
77
+ hot_threshold = temperatures.mean() + 2 * temperatures.std()
78
+ hot_spots = temperatures > hot_threshold
79
+ hot_count = np.sum(hot_spots)
80
+
81
+ print(f"\n=== HOT SPOT ANALYSIS ===")
82
+ print(f"Hot spots (> {hot_threshold:.1f}°C): {hot_count} pixels")
83
+ print(f"Hot spot percentage: {100 * hot_count / temperatures.size:.1f}%")
84
+
85
+ if hot_count > 0:
86
+ hot_temps = temperatures[hot_spots]
87
+ print(f"Hot spot temperature range: {hot_temps.min():.1f}°C - {hot_temps.max():.1f}°C")
88
+
89
+ except FileNotFoundError:
90
+ print(f"Error: File {file_path} not found.")
91
+ print("Please replace 'thermal_image.is2' with the path to your actual .is2 file.")
92
+ except Exception as e:
93
+ print(f"Error loading thermal data: {e}")
94
+
95
+ if __name__ == "__main__":
96
+ main()