Coverage analysis implemented.
This commit is contained in:
parent
eed449ddd1
commit
80c4a9c0a1
5 changed files with 103 additions and 8 deletions
|
|
@ -24,7 +24,7 @@ class Image {
|
||||||
/// @brief Colormaps LUTs.
|
/// @brief Colormaps LUTs.
|
||||||
struct Colormap {
|
struct Colormap {
|
||||||
/// @brief MATLAB's parula colormap. 256x3 values : R0G0B0, R1G1B1, ...
|
/// @brief MATLAB's parula colormap. 256x3 values : R0G0B0, R1G1B1, ...
|
||||||
static constexpr unsigned char PARULA_256[256*3] = {62,38,168 ,62,39,172 ,63,40,175 ,63,41,178 ,64,42,180 ,64,43,183 ,65,44,186 ,65,45,189 ,66,46,191 ,66,47,194 ,67,48,197 ,67,49,200 ,67,50,202 ,68,51,205 ,68,52,208 ,69,53,210 ,69,55,213 ,69,56,215 ,70,57,217 ,70,58,220 ,70,59,222 ,70,61,224 ,71,62,225 ,71,63,227 ,71,65,229 ,71,66,230 ,71,68,232 ,71,69,233 ,71,70,235 ,72,72,236 ,72,73,237 ,72,75,238 ,72,76,240 ,72,78,241 ,72,79,242 ,72,80,243 ,72,82,244 ,72,83,245 ,72,84,246 ,71,86,247 ,71,87,247 ,71,89,248 ,71,90,249 ,71,91,250 ,71,93,250 ,70,94,251 ,70,96,251 ,70,97,252 ,69,98,252 ,69,100,253 ,68,101,253 ,67,103,253 ,67,104,254 ,66,106,254 ,65,107,254 ,64,109,254 ,63,110,255 ,62,112,255 ,60,113,255 ,59,115,255 ,57,116,255 ,56,118,254 ,54,119,254 ,53,121,253 ,51,122,253 ,50,124,252 ,49,125,252 ,48,127,251 ,47,128,250 ,47,130,250 ,46,131,249 ,46,132,248 ,46,134,248 ,46,135,247 ,45,136,246 ,45,138,245 ,45,139,244 ,45,140,243 ,45,142,242 ,44,143,241 ,44,144,240 ,43,145,239 ,42,147,238 ,41,148,237 ,40,149,236 ,39,151,235 ,39,152,234 ,38,153,233 ,38,154,232 ,37,155,232 ,37,156,231 ,36,158,230 ,36,159,229 ,35,160,229 ,35,161,228 ,34,162,228 ,33,163,227 ,32,165,227 ,31,166,226 ,30,167,225 ,29,168,225 ,29,169,224 ,28,170,223 ,27,171,222 ,26,172,221 ,25,173,220 ,23,174,218 ,22,175,217 ,20,176,216 ,18,177,214 ,16,178,213 ,14,179,212 ,11,179,210 ,8,180,209 ,6,181,207 ,4,182,206 ,2,183,204 ,1,183,202 ,0,184,201 ,0,185,199 ,0,186,198 ,1,186,196 ,2,187,194 ,4,187,193 ,6,188,191 ,9,189,189 ,13,189,188 ,16,190,186 ,20,190,184 ,23,191,182 ,26,192,181 ,29,192,179 ,32,193,177 ,35,193,175 ,37,194,174 ,39,194,172 ,41,195,170 ,43,195,168 ,44,196,166 ,46,196,165 ,47,197,163 ,49,197,161 ,50,198,159 ,51,199,157 ,53,199,155 ,54,200,153 ,56,200,150 ,57,201,148 ,59,201,146 ,61,202,144 ,64,202,141 ,66,202,139 ,69,203,137 ,72,203,134 ,75,203,132 ,78,204,129 ,81,204,127 ,84,204,124 ,87,204,122 ,90,204,119 ,94,205,116 ,97,205,114 ,100,205,111 ,103,205,108 ,107,205,105 ,110,205,102 ,114,205,100 ,118,204,97 ,121,204,94 ,125,204,91 ,129,204,89 ,132,204,86 ,136,203,83 ,139,203,81 ,143,203,78 ,147,202,75 ,150,202,72 ,154,201,70 ,157,201,67 ,161,200,64 ,164,200,62 ,167,199,59 ,171,199,57 ,174,198,55 ,178,198,53 ,181,197,51 ,184,196,49 ,187,196,47 ,190,195,45 ,194,195,44 ,197,194,42 ,200,193,41 ,203,193,40 ,206,192,39 ,208,191,39 ,211,191,39 ,214,190,39 ,217,190,40 ,219,189,40 ,222,188,41 ,225,188,42 ,227,188,43 ,230,187,45 ,232,187,46 ,234,186,48 ,236,186,50 ,239,186,53 ,241,186,55 ,243,186,57 ,245,186,59 ,247,186,61 ,249,186,62 ,251,187,62 ,252,188,62 ,254,189,61 ,254,190,60 ,254,192,59 ,254,193,58 ,254,194,57 ,254,196,56 ,254,197,55 ,254,199,53 ,254,200,52 ,254,202,51 ,253,203,50 ,253,205,49 ,253,206,49 ,252,208,48 ,251,210,47 ,251,211,46 ,250,213,46 ,249,214,45 ,249,216,44 ,248,217,43 ,247,219,42 ,247,221,42 ,246,222,41 ,246,224,40 ,245,225,40 ,245,227,39 ,245,229,38 ,245,230,38 ,245,232,37 ,245,233,36 ,245,235,35 ,245,236,34 ,245,238,33 ,246,239,32 ,246,241,31 ,246,242,30 ,247,244,28 ,247,245,27 ,248,247,26 ,248,248,24 ,249,249,22 ,249,251,21};
|
static constexpr unsigned char PARULA[256*3] = {62,38,168 ,62,39,172 ,63,40,175 ,63,41,178 ,64,42,180 ,64,43,183 ,65,44,186 ,65,45,189 ,66,46,191 ,66,47,194 ,67,48,197 ,67,49,200 ,67,50,202 ,68,51,205 ,68,52,208 ,69,53,210 ,69,55,213 ,69,56,215 ,70,57,217 ,70,58,220 ,70,59,222 ,70,61,224 ,71,62,225 ,71,63,227 ,71,65,229 ,71,66,230 ,71,68,232 ,71,69,233 ,71,70,235 ,72,72,236 ,72,73,237 ,72,75,238 ,72,76,240 ,72,78,241 ,72,79,242 ,72,80,243 ,72,82,244 ,72,83,245 ,72,84,246 ,71,86,247 ,71,87,247 ,71,89,248 ,71,90,249 ,71,91,250 ,71,93,250 ,70,94,251 ,70,96,251 ,70,97,252 ,69,98,252 ,69,100,253 ,68,101,253 ,67,103,253 ,67,104,254 ,66,106,254 ,65,107,254 ,64,109,254 ,63,110,255 ,62,112,255 ,60,113,255 ,59,115,255 ,57,116,255 ,56,118,254 ,54,119,254 ,53,121,253 ,51,122,253 ,50,124,252 ,49,125,252 ,48,127,251 ,47,128,250 ,47,130,250 ,46,131,249 ,46,132,248 ,46,134,248 ,46,135,247 ,45,136,246 ,45,138,245 ,45,139,244 ,45,140,243 ,45,142,242 ,44,143,241 ,44,144,240 ,43,145,239 ,42,147,238 ,41,148,237 ,40,149,236 ,39,151,235 ,39,152,234 ,38,153,233 ,38,154,232 ,37,155,232 ,37,156,231 ,36,158,230 ,36,159,229 ,35,160,229 ,35,161,228 ,34,162,228 ,33,163,227 ,32,165,227 ,31,166,226 ,30,167,225 ,29,168,225 ,29,169,224 ,28,170,223 ,27,171,222 ,26,172,221 ,25,173,220 ,23,174,218 ,22,175,217 ,20,176,216 ,18,177,214 ,16,178,213 ,14,179,212 ,11,179,210 ,8,180,209 ,6,181,207 ,4,182,206 ,2,183,204 ,1,183,202 ,0,184,201 ,0,185,199 ,0,186,198 ,1,186,196 ,2,187,194 ,4,187,193 ,6,188,191 ,9,189,189 ,13,189,188 ,16,190,186 ,20,190,184 ,23,191,182 ,26,192,181 ,29,192,179 ,32,193,177 ,35,193,175 ,37,194,174 ,39,194,172 ,41,195,170 ,43,195,168 ,44,196,166 ,46,196,165 ,47,197,163 ,49,197,161 ,50,198,159 ,51,199,157 ,53,199,155 ,54,200,153 ,56,200,150 ,57,201,148 ,59,201,146 ,61,202,144 ,64,202,141 ,66,202,139 ,69,203,137 ,72,203,134 ,75,203,132 ,78,204,129 ,81,204,127 ,84,204,124 ,87,204,122 ,90,204,119 ,94,205,116 ,97,205,114 ,100,205,111 ,103,205,108 ,107,205,105 ,110,205,102 ,114,205,100 ,118,204,97 ,121,204,94 ,125,204,91 ,129,204,89 ,132,204,86 ,136,203,83 ,139,203,81 ,143,203,78 ,147,202,75 ,150,202,72 ,154,201,70 ,157,201,67 ,161,200,64 ,164,200,62 ,167,199,59 ,171,199,57 ,174,198,55 ,178,198,53 ,181,197,51 ,184,196,49 ,187,196,47 ,190,195,45 ,194,195,44 ,197,194,42 ,200,193,41 ,203,193,40 ,206,192,39 ,208,191,39 ,211,191,39 ,214,190,39 ,217,190,40 ,219,189,40 ,222,188,41 ,225,188,42 ,227,188,43 ,230,187,45 ,232,187,46 ,234,186,48 ,236,186,50 ,239,186,53 ,241,186,55 ,243,186,57 ,245,186,59 ,247,186,61 ,249,186,62 ,251,187,62 ,252,188,62 ,254,189,61 ,254,190,60 ,254,192,59 ,254,193,58 ,254,194,57 ,254,196,56 ,254,197,55 ,254,199,53 ,254,200,52 ,254,202,51 ,253,203,50 ,253,205,49 ,253,206,49 ,252,208,48 ,251,210,47 ,251,211,46 ,250,213,46 ,249,214,45 ,249,216,44 ,248,217,43 ,247,219,42 ,247,221,42 ,246,222,41 ,246,224,40 ,245,225,40 ,245,227,39 ,245,229,38 ,245,230,38 ,245,232,37 ,245,233,36 ,245,235,35 ,245,236,34 ,245,238,33 ,246,239,32 ,246,241,31 ,246,242,30 ,247,244,28 ,247,245,27 ,248,247,26 ,248,248,24 ,249,249,22 ,249,251,21};
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @brief Initializes the image with the given width, height, and optionally depth. Warning : the values are uninitialized.
|
/// @brief Initializes the image with the given width, height, and optionally depth. Warning : the values are uninitialized.
|
||||||
|
|
@ -133,7 +133,21 @@ class Image {
|
||||||
/// All channels are used to compute the histogram, and all channels are normalized using the same global histogram.
|
/// All channels are used to compute the histogram, and all channels are normalized using the same global histogram.
|
||||||
/// @param downsampling_factor Downsampling factor to use while computing the histogram.
|
/// @param downsampling_factor Downsampling factor to use while computing the histogram.
|
||||||
/// @return A reference to the image.
|
/// @return A reference to the image.
|
||||||
Image & HistogramNormalize(int downsampling_factor=1);
|
Image & HistogramNormalize(int downsampling_factor = 1);
|
||||||
|
|
||||||
|
/// @brief Returns a histrogram-normalized copy of the image. Histogram normalization is a contrast enhancement technique that ensures that the whole range of values is used.
|
||||||
|
/// All channels are used to compute the histogram, and all channels are normalized using the same global histogram.
|
||||||
|
/// @param downsampling_factor Downsampling factor to use while computing the histogram.
|
||||||
|
/// @return A reference to the image.
|
||||||
|
Image HistogramNormalized(int downsampling_factor = 1) const;
|
||||||
|
|
||||||
|
/// @brief Normalizes the image (in place), so that the minimum value is 0 and the maximum value is 255.
|
||||||
|
/// @return A reference to the image.
|
||||||
|
Image & Normalize();
|
||||||
|
|
||||||
|
/// @brief Returns a normalized copy of the image, so that the minimum value is 0 and the maximum value is 255.
|
||||||
|
/// @return A normalized copy of the image.
|
||||||
|
Image Normalized() const;
|
||||||
|
|
||||||
/// @brief Applies a colormap to the image. After applying the colormap, the image will be 3-channel (RGB). If the image is not single-channel, a unnchanged copy of the image is returned.
|
/// @brief Applies a colormap to the image. After applying the colormap, the image will be 3-channel (RGB). If the image is not single-channel, a unnchanged copy of the image is returned.
|
||||||
/// @param colormap Array of 256*3 values, representing the RGB values of the colormap. Order is R0, G0, B0, R1, G1, B1, etc.
|
/// @param colormap Array of 256*3 values, representing the RGB values of the colormap. Order is R0, G0, B0, R1, G1, B1, etc.
|
||||||
|
|
|
||||||
|
|
@ -2,16 +2,23 @@
|
||||||
#define H_Slicer360ToPerspective
|
#define H_Slicer360ToPerspective
|
||||||
|
|
||||||
#include <Camera.hpp>
|
#include <Camera.hpp>
|
||||||
|
#include <Image.hpp>
|
||||||
|
|
||||||
/// @brief This class encapsulates the algorithms to convert a 360-degree image to a perspective image.
|
/// @brief This class encapsulates the algorithms to convert a 360-degree image to a perspective image.
|
||||||
class Slicer360ToPerspective {
|
class Slicer360ToPerspective {
|
||||||
public:
|
public:
|
||||||
Slicer360ToPerspective();
|
Slicer360ToPerspective();
|
||||||
|
|
||||||
|
/// @brief Computes the coverage of the 360-degree image by the cameras added to the slicer.
|
||||||
|
/// @param width Width of the generated 360-degree image containing the results of the analysis.
|
||||||
|
/// @param raw If true, the output is the number of cameras that see the pixel of the 360 image (8-bit monochrome image). If false, the output is a colored RGB image.
|
||||||
|
/// @return The coverage of the 360-degree image.
|
||||||
|
Image ComputeCoverage(int width, bool raw = false);
|
||||||
|
|
||||||
|
std::vector<Camera> cameras;//!< A vector of cameras that are used to convert the 360-degree image to perspective images.
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<Camera> cameras;//!< A vector of cameras that are used to convert the 360-degree image to perspective images.
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -161,6 +161,35 @@ Image & Image::HistogramNormalize(int downsampling_factor) {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Image Image::HistogramNormalized(int downsampling_factor) const {
|
||||||
|
Image normalized(*this);
|
||||||
|
normalized.HistogramNormalize(downsampling_factor);
|
||||||
|
return normalized;
|
||||||
|
}
|
||||||
|
|
||||||
|
Image & Image::Normalize() {
|
||||||
|
// First, compute the min and max values using all channels
|
||||||
|
unsigned char min_val = 255, max_val = 0;
|
||||||
|
for(int i = 0 ; i < width*height*depth ; i++) {
|
||||||
|
if(data[i] < min_val)
|
||||||
|
min_val = data[i];
|
||||||
|
else if(data[i] > max_val)
|
||||||
|
max_val = data[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then, normalize the image
|
||||||
|
for(int i = 0 ; i < width*height*depth ; i++)
|
||||||
|
data[i] = ((int)data[i] - min_val) * 255 / (max_val - min_val);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Image Image::Normalized() const {
|
||||||
|
Image normalized(*this);
|
||||||
|
normalized.Normalize();
|
||||||
|
return normalized;
|
||||||
|
}
|
||||||
|
|
||||||
Image Image::Colorized(unsigned char const* colormap) const {
|
Image Image::Colorized(unsigned char const* colormap) const {
|
||||||
if (depth != 1)
|
if (depth != 1)
|
||||||
return *this;
|
return *this;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,34 @@
|
||||||
#include <Slicer360ToPerspective.hpp>
|
#include <Slicer360ToPerspective.hpp>
|
||||||
|
#include <frame_conversions.hpp>
|
||||||
|
|
||||||
Slicer360ToPerspective::Slicer360ToPerspective()
|
Slicer360ToPerspective::Slicer360ToPerspective()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Image Slicer360ToPerspective::ComputeCoverage(int width, bool raw)
|
||||||
|
{
|
||||||
|
int height = width/2;
|
||||||
|
Image coverage(width, height, 1);
|
||||||
|
|
||||||
|
// Compute the coverage of the 360-degree image by the cameras added to the slicer.
|
||||||
|
for(int i = 0; i < height; i++) {
|
||||||
|
for(int j = 0; j < width; j++) {
|
||||||
|
// Compute view vector in inertial frame from equirectangular coordinates
|
||||||
|
Eigen::Vector3d ray_dir_sph = equirectangular2sph(i, j, width, height);
|
||||||
|
Eigen::Vector3d ray_dir_cart = sph2cart(ray_dir_sph);
|
||||||
|
int count = 0;
|
||||||
|
for(Camera const& camera : cameras)
|
||||||
|
{
|
||||||
|
if(camera.IsPointVisibleInertialFrame(ray_dir_cart))
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
coverage.SetPixelValue(i, j, 0, count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(raw)
|
||||||
|
return coverage;
|
||||||
|
else
|
||||||
|
return coverage.Normalized().Colorized(Image::Colormap::PARULA);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <Camera.hpp>
|
#include <Camera.hpp>
|
||||||
#include <Image.hpp>
|
#include <Image.hpp>
|
||||||
|
#include <Slicer360ToPerspective.hpp>
|
||||||
|
|
||||||
#define _USE_MATH_DEFINES
|
#define _USE_MATH_DEFINES
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
@ -75,7 +76,7 @@ int main() {
|
||||||
std::cout.precision(16);
|
std::cout.precision(16);
|
||||||
std::cout << "Running Unit Tests\n";
|
std::cout << "Running Unit Tests\n";
|
||||||
|
|
||||||
{// Camera
|
if(0){// Camera
|
||||||
std::cout << "Camera\n";
|
std::cout << "Camera\n";
|
||||||
{// Constructor, accessors and setters
|
{// Constructor, accessors and setters
|
||||||
std::cout << "Constructor, accessors and setters\n";
|
std::cout << "Constructor, accessors and setters\n";
|
||||||
|
|
@ -167,7 +168,7 @@ int main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{// Image
|
if(0){// Image
|
||||||
std::cout << "Image\n";
|
std::cout << "Image\n";
|
||||||
{
|
{
|
||||||
std::cout << "Constructors\n";
|
std::cout << "Constructors\n";
|
||||||
|
|
@ -302,7 +303,7 @@ int main() {
|
||||||
image_luma.Save("venise_luma.jpg");
|
image_luma.Save("venise_luma.jpg");
|
||||||
|
|
||||||
std::cout << "Colormap application\n";
|
std::cout << "Colormap application\n";
|
||||||
Image image_parula = image_luma.Colorized(Image::Colormap::PARULA_256);
|
Image image_parula = image_luma.Colorized(Image::Colormap::PARULA);
|
||||||
image_parula.Save("venise_parula.jpg");
|
image_parula.Save("venise_parula.jpg");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -314,6 +315,22 @@ int main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
std::cout << "Coverage analysis\n";
|
||||||
|
Slicer360ToPerspective slicer;
|
||||||
|
|
||||||
|
double fov = 90.0*DEG2RAD;
|
||||||
|
int width = 500;
|
||||||
|
slicer.cameras.push_back(Camera().SetFOV(fov).SetTarget(Eigen::Vector3d(1., 0., 0.)));
|
||||||
|
slicer.cameras.push_back(Camera().SetFOV(fov).SetTarget(Eigen::Vector3d(-1., -1., -1.)));
|
||||||
|
slicer.cameras.push_back(Camera().SetFOV(fov/2).SetTarget(Eigen::Vector3d(1., 0.2, -0.3)));
|
||||||
|
Image coverage_raw = slicer.ComputeCoverage(width, true);
|
||||||
|
Image coverage_col = slicer.ComputeCoverage(width, false);
|
||||||
|
|
||||||
|
coverage_raw.Save("coverage_raw.png");
|
||||||
|
coverage_col.Save("coverage_col.png");
|
||||||
|
}
|
||||||
|
|
||||||
PRINT_TESTS_SUMMARY();
|
PRINT_TESTS_SUMMARY();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue