-
Notifications
You must be signed in to change notification settings - Fork 10
/
image.h
359 lines (304 loc) · 15.9 KB
/
image.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
#pragma once
#include "imgui.h"
#include <opencv2/core.hpp>
#include <vector>
#include <string>
// IMMVISION_API is a marker for public API functions. IMMVISION_STRUCT_API is a marker for public API structs (in comment lines)
// Usage of ImmVision as a shared library is not recommended. No guaranty of ABI stability is provided
#ifndef IMMVISION_API
#define IMMVISION_API
#endif
namespace ImmVision
{
// Set the color order for displayed images.
// You **must** call once at the start of your program:
// ImmVision::UseRgbColorOrder() or ImmVision::UseBgrColorOrder() (C++)
// immvision.use_rgb_color_order() or immvision.use_bgr_color_order() (Python)
// (Breaking change - October 2024)
void UseRgbColorOrder();
void UseBgrColorOrder();
// Returns true if we are using RGB color order
bool IsUsingRgbColorOrder();
// Returns true if we are using BGR color order
bool IsUsingBgrColorOrder();
// Returns true if the color order is undefined (i.e. UseRgbColorOrder or UseBgrColorOrder was not called)
bool IsColorOrderUndefined();
// Temporary change of color order (useful for displaying a single image with a different color order)
void PushColorOrderRgb();
void PushColorOrderBgr();
void PopColorOrder();
// Are we using the stats on the full image, on the Visible ROI, or are we using Min/Max values
enum class ColorMapStatsTypeId
{
FromFullImage,
FromVisibleROI
};
// Scale the Colormap according to the Image stats
struct ColormapScaleFromStatsData // IMMVISION_API_STRUCT
{
// Are we using the stats on the full image, the visible ROI, or are we using Min/Max values
ColorMapStatsTypeId ColorMapStatsType = ColorMapStatsTypeId::FromFullImage;
// If stats active (either on ROI or on Image), how many sigmas around the mean should the Colormap be applied
double NbSigmas = 1.5;
// If ColorMapScaleType==ColorMapStatsType::FromMinMax, then ColormapScaleMin will be calculated from the matrix min value instead of a sigma based value
bool UseStatsMin = false;
// If ColorMapScaleType==ColorMapStatsType::FromMinMax, then ColormapScaleMax will be calculated from the matrix min value instead of a sigma based value
bool UseStatsMax = false;
};
// Colormap Settings (useful for matrices with one channel, in order to see colors mapping float values)
struct ColormapSettingsData // IMMVISION_API_STRUCT
{
// Colormap, see available Colormaps with AvailableColormaps()
// Work only with 1 channel matrices, i.e len(shape)==2
std::string Colormap = "None";
// ColormapScaleMin and ColormapScaleMax indicate how the Colormap is applied:
// - Values in [ColormapScaleMin, ColomapScaleMax] will use the full colormap.
// - Values outside this interval will be clamped before coloring
// by default, the initial values are ignored, and they will be updated automatically
// via the options in ColormapScaleFromStats
double ColormapScaleMin = 0.;
double ColormapScaleMax = 1.;
// If ColormapScaleFromStats.ActiveOnFullImage or ColormapScaleFromStats.ActiveOnROI,
// then ColormapScaleMin/Max are ignored, and the scaling is done according to the image stats.
// ColormapScaleFromStats.ActiveOnFullImage is true by default
ColormapScaleFromStatsData ColormapScaleFromStats = ColormapScaleFromStatsData();
// Internal value: stores the name of the Colormap that is hovered by the mouse
std::string internal_ColormapHovered = "";
};
// Contains information about the mouse inside an image
struct MouseInformation // IMMVISION_API_STRUCT
{
// Is the mouse hovering the image
bool IsMouseHovering = false;
// Mouse position in the original image/matrix
// This position is given with float coordinates, and will be (-1., -1.) if the mouse is not hovering the image
cv::Point2d MousePosition = cv::Point2d(-1., -1.);
// Mouse position in the displayed portion of the image (the original image can be zoomed,
// and only show a subset if it may be shown).
// This position is given with integer coordinates, and will be (-1, -1) if the mouse is not hovering the image
cv::Point MousePosition_Displayed = cv::Point(-1, -1);
//
// Note: you can query ImGui::IsMouseDown(mouse_button) (c++) or imgui.is_mouse_down(mouse_button) (Python)
//
};
// Set of display parameters and options for an Image
struct ImageParams // IMMVISION_API_STRUCT
{
//
// ImageParams store the parameters for a displayed image
// (as well as user selected watched pixels, selected channel, etc.)
// Its default constructor will give them reasonable choices, which you can adapt to your needs.
// Its values will be updated when the user pans or zooms the image, adds watched pixels, etc.
//
//
// Refresh Images Textures
//
// Refresh Image: images textures are cached. Set to true if your image matrix/buffer has changed
// (for example, for live video images)
bool RefreshImage = false;
//
// Display size and title
//
// Size of the displayed image (can be different from the matrix size)
// If you specify only the width or height (e.g (300, 0), then the other dimension
// will be calculated automatically, respecting the original image w/h ratio.
cv::Size ImageDisplaySize = cv::Size();
//
// Zoom and Pan (represented by an affine transform matrix, of size 3x3)
//
// ZoomPanMatrix can be created using MakeZoomPanMatrix to create a view centered around a given point
cv::Matx33d ZoomPanMatrix = cv::Matx33d::eye();
// If displaying several images, those with the same ZoomKey will zoom and pan together
std::string ZoomKey = "";
//
// Colormap Settings (useful for matrices with one channel, in order to see colors mapping float values)
//
// ColormapSettings stores all the parameter concerning the Colormap
ColormapSettingsData ColormapSettings = ColormapSettingsData();
// If displaying several images, those with the same ColormapKey will adjust together
std::string ColormapKey = "";
//
// Zoom and pan with the mouse
//
bool PanWithMouse = true;
bool ZoomWithMouseWheel = true;
// Can the image widget be resized by the user
bool CanResize = true;
// Does the widget keep an aspect ratio equal to the image when resized
bool ResizeKeepAspectRatio = true;
//
// Image display options
//
// if SelectedChannel >= 0 then only this channel is displayed
int SelectedChannel = -1;
// Show a "school paper" background grid
bool ShowSchoolPaperBackground = true;
// show a checkerboard behind transparent portions of 4 channels RGBA images
bool ShowAlphaChannelCheckerboard = true;
// Grid displayed when the zoom is high
bool ShowGrid = true;
// Pixel values show when the zoom is high
bool DrawValuesOnZoomedPixels = true;
//
// Image display options
//
// Show matrix type and size
bool ShowImageInfo = true;
// Show pixel values
bool ShowPixelInfo = true;
// Show buttons that enable to zoom in/out (the mouse wheel also zoom)
bool ShowZoomButtons = true;
// Open the options panel
bool ShowOptionsPanel = false;
// If set to true, then the option panel will be displayed in a transient tooltip window
bool ShowOptionsInTooltip = false;
// If set to false, then the Options button will not be displayed
bool ShowOptionsButton = true;
//
// Watched Pixels
//
// List of Watched Pixel coordinates
std::vector<cv::Point> WatchedPixels = std::vector<cv::Point>();
// Shall we add a watched pixel on double click
bool AddWatchedPixelOnDoubleClick = true;
// Shall the watched pixels be drawn on the image
bool HighlightWatchedPixels = true;
// Mouse position information. These values are filled after displaying an image
MouseInformation MouseInfo = MouseInformation();
~ImageParams();
};
#ifdef IMMVISION_SERIALIZE_JSON
IMMVISION_API std::string ImageParamsToJson(const ImageParams& params);
IMMVISION_API void FillImageParamsFromJson(const std::string& json, ImageParams* params);
IMMVISION_API ImageParams ImageParamsFromJson(const std::string& json);
#endif
// Create ImageParams that display the image only, with no decoration, and no user interaction
IMMVISION_API ImageParams FactorImageParamsDisplayOnly();
// Create a zoom/pan matrix centered around a given point of interest
IMMVISION_API cv::Matx33d MakeZoomPanMatrix(
const cv::Point2d & zoomCenter,
double zoomRatio,
const cv::Size displayedImageSize
);
IMMVISION_API cv::Matx33d MakeZoomPanMatrix_ScaleOne(
cv::Size imageSize,
const cv::Size displayedImageSize
);
IMMVISION_API cv::Matx33d MakeZoomPanMatrix_FullView(
cv::Size imageSize,
const cv::Size displayedImageSize
);
// Display an image, with full user control: zoom, pan, watch pixels, etc.
//
// :param label
// A legend that will be displayed.
// Important notes:
// - With ImGui and ImmVision, widgets *must* have a unique Ids.
// For this widget, the id is given by this label.
// Two widgets (for example) two images *cannot* have the same label or the same id!
// (you can use ImGui::PushID / ImGui::PopID to circumvent this, or add suffixes with ##)
//
// If they do, they might not refresh correctly!
// To circumvent this, you can:
// - Call `ImGui::PushID("some_unique_string")` at the start of your function,
// and `ImGui::PopID()` at the end.
// - Or modify your label like this:
// "MyLabel##some_unique_id"
// (the part after "##" will not be displayed but will be part of the id)
// - To display an empty legend, use "##_some_unique_id"
//
// :param mat
// An image you want to display, under the form of an OpenCV matrix. All types of dense matrices are supported.
//
// :param params
// Complete options (as modifiable inputs), and outputs (mouse position, watched pixels, etc)
// @see ImageParams structure.
// The ImageParams may be modified by this function: you can extract from them
// the mouse position, watched pixels, etc.
// Important note:
// ImageParams is an input-output parameter, passed as a pointer.
// Its scope should be wide enough so that it is preserved from frame to frame.
// !! If you cannot zoom/pan in a displayed image, extend the scope of the ImageParams !!
//
// - This function requires that both imgui and OpenGL were initialized.
// (for example, use `imgui_runner.run`for Python, or `HelloImGui::Run` for C++)
IMMVISION_API void Image(const std::string& label, const cv::Mat& mat, ImageParams* params);
// ImageDisplay: Only, display the image, with no user interaction (by default)
//
// Parameters:
// :param label_id
// A legend that will be displayed.
// Important notes:
// - With ImGui and ImmVision, widgets must have a unique Ids. For this widget, the id is given by this label.
// Two widgets (for example) two images *cannot* have the same label or the same id!
// If they do, they might not refresh correctly!
// To circumvent this, you can modify your label like this:
// "MyLabel##some_unique_id" (the part after "##" will not be displayed but will be part of the id)
// - To display an empty legend, use "##_some_unique_id"
// - if your legend is displayed (i.e. it does not start with "##"),
// then the total size of the widget will be larger than the imageDisplaySize.
//
// :param mat:
// An image you want to display, under the form of an OpenCV matrix. All types of dense matrices are supported.
//
// :param imageDisplaySize:
// Size of the displayed image (can be different from the mat size)
// If you specify only the width or height (e.g (300, 0), then the other dimension
// will be calculated automatically, respecting the original image w/h ratio.
//
// :param refreshImage:
// images textures are cached. Set to true if your image matrix/buffer has changed
// (for example, for live video images)
//
// :param showOptionsButton:
// If true, show an option button that opens the option panel.
// In that case, it also becomes possible to zoom & pan, add watched pixel by double-clicking, etc.
//
// :param isBgrOrBgra:
// set to true if the color order of the image is BGR or BGRA (as in OpenCV)
//. Breaking change, oct 2024: the default is BGR for C++, RGB for Python!
//
// :return:
// The mouse position in `mat` original image coordinates, as double values.
// (i.e. it does not matter if imageDisplaySize is different from mat.size())
// It will return (-1., -1.) if the mouse is not hovering the image.
//
// Note: use ImGui::IsMouseDown(mouse_button) (C++) or imgui.is_mouse_down(mouse_button) (Python)
// to query more information about the mouse.
//
// Note: this function requires that both imgui and OpenGL were initialized.
// (for example, use `imgui_runner.run`for Python, or `HelloImGui::Run` for C++)
//
IMMVISION_API cv::Point2d ImageDisplay(
const std::string& label_id,
const cv::Mat& mat,
const cv::Size& imageDisplaySize = cv::Size(),
bool refreshImage = false,
bool showOptionsButton = false
);
// ImageDisplayResizable: display the image, with no user interaction (by default)
// The image can be resized by the user (and the new size will be stored in the size parameter, if provided)
// The label will not be displayed (but it will be used as an id, and must be unique)
IMMVISION_API cv::Point2d ImageDisplayResizable(
const std::string& label_id,
const cv::Mat& mat,
ImVec2* size = nullptr,
bool refreshImage = false,
bool resizable = true,
bool showOptionsButton = false
);
// Return the list of the available color maps
// Taken from https://github.com/yuki-koyama/tinycolormap, thanks to Yuki Koyama
IMMVISION_API std::vector<std::string> AvailableColormaps();
// Clears the internal texture cache of immvision (this is done automatically at exit time)
//
// Note: this function requires that both imgui and OpenGL were initialized.
// (for example, use `imgui_runner.run`for Python, or `HelloImGui::Run` for C++)
IMMVISION_API void ClearTextureCache();
// Returns the RGBA image currently displayed by ImmVision::Image or ImmVision::ImageDisplay
// Note: this image must be currently displayed. This function will return the transformed image
// (i.e with ColorMap, Zoom, etc.)
IMMVISION_API cv::Mat GetCachedRgbaImage(const std::string& label);
// Return immvision version info
IMMVISION_API std::string VersionInfo();
} // namespace ImmVision