v1.0.0-rc.110 (#16)
Build Packages / build:rpm (rocky8_nocuda) (push) Successful in 7m46s
Build Packages / build:rpm (rocky9_nocuda) (push) Successful in 8m45s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Successful in 6m56s
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Successful in 5m58s
Build Packages / build:rpm (rocky8_sls9) (push) Successful in 6m59s
Build Packages / build:rpm (rocky8) (push) Successful in 7m33s
Build Packages / Generate python client (push) Successful in 19s
Build Packages / Build documentation (push) Successful in 41s
Build Packages / Create release (push) Has been skipped
Build Packages / build:rpm (rocky9) (push) Successful in 8m45s
Build Packages / build:rpm (ubuntu2204) (push) Successful in 7m51s
Build Packages / build:rpm (ubuntu2404) (push) Successful in 7m12s
Build Packages / Unit tests (push) Successful in 1h8m51s
Build Packages / build:rpm (rocky8_nocuda) (push) Successful in 7m46s
Build Packages / build:rpm (rocky9_nocuda) (push) Successful in 8m45s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Successful in 6m56s
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Successful in 5m58s
Build Packages / build:rpm (rocky8_sls9) (push) Successful in 6m59s
Build Packages / build:rpm (rocky8) (push) Successful in 7m33s
Build Packages / Generate python client (push) Successful in 19s
Build Packages / Build documentation (push) Successful in 41s
Build Packages / Create release (push) Has been skipped
Build Packages / build:rpm (rocky9) (push) Successful in 8m45s
Build Packages / build:rpm (ubuntu2204) (push) Successful in 7m51s
Build Packages / build:rpm (ubuntu2404) (push) Successful in 7m12s
Build Packages / Unit tests (push) Successful in 1h8m51s
This is an UNSTABLE release. * jfjoch_broker: Add auto-contrast option for preview images * Frontend: Add logo image * jfjoch_viewer: Add logo image * jfjoch_viewer: For image chart allow to set min value to zero * jfjoch_viewer: For resolution estimation plots, visualization uses 1/d^2 as measure * jfjoch_viewer: Add 3D unit cell visualization (experimental/WIP/not really there) * Documentation: Add logo image Reviewed-on: #16 Co-authored-by: Filip Leonarski <filip.leonarski@psi.ch> Co-committed-by: Filip Leonarski <filip.leonarski@psi.ch>
This commit was merged in pull request #16.
This commit is contained in:
+54
-26
@@ -48,14 +48,46 @@ void PreviewImage::roi(std::vector<rgb> &ret, int64_t in_xpixel, int64_t in_ypix
|
||||
}
|
||||
|
||||
template<class T>
|
||||
std::vector<rgb> PreviewImage::GenerateRGB(const uint8_t* value_8,
|
||||
std::vector<rgb> PreviewImage::GenerateRGB(const uint8_t *value_8,
|
||||
int64_t special_value_64,
|
||||
int64_t sat_value_64,
|
||||
const ColorScale &scale,
|
||||
const PreviewImageSettings& settings) const {
|
||||
const PreviewImageSettings &settings) const {
|
||||
auto value = reinterpret_cast<const T *>(value_8);
|
||||
auto special_value = static_cast<T>(special_value_64);
|
||||
|
||||
std::vector<rgb> ret(xpixel*ypixel);
|
||||
float background = settings.background_value.value_or(0.0);
|
||||
float foreground;
|
||||
if (settings.saturation_value.has_value())
|
||||
foreground = settings.saturation_value.value();
|
||||
else {
|
||||
// Auto-contrast procedure
|
||||
std::vector<int64_t> valid;
|
||||
valid.reserve(xpixel * ypixel);
|
||||
for (int i = 0; i < xpixel * ypixel; i++) {
|
||||
if ((value[i] != special_value)
|
||||
&& (value[i] != sat_value_64)
|
||||
&& (mask[i] != MaskDet)
|
||||
&& (mask[i] != MaskGap)
|
||||
&& (!settings.show_user_mask || (mask[i] != MaskUsr)))
|
||||
valid.push_back(static_cast<int64_t>(value[i]));
|
||||
}
|
||||
|
||||
if (!valid.empty()) {
|
||||
const size_t m = valid.size();
|
||||
size_t ignore = std::max<size_t>(1, static_cast<size_t>(std::floor(m * auto_foreground_range)));
|
||||
if (ignore >= m) ignore = m - 1; // ensure at least one value remains
|
||||
const size_t rank = m - ignore - 1; // 0-based index for the desired value
|
||||
std::nth_element(valid.begin(), valid.begin() + rank, valid.end());
|
||||
foreground = static_cast<float>(valid[rank]);
|
||||
} else {
|
||||
// Fallback to something above background if no valid pixels remain
|
||||
foreground = background + 1.0f;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::vector<rgb> ret(xpixel * ypixel);
|
||||
for (int i = 0; i < xpixel*ypixel; i++) {
|
||||
if (mask[i] == MaskGap)
|
||||
ret[i] = scale.Apply(ColorScaleSpecial::Gap);
|
||||
@@ -64,7 +96,7 @@ std::vector<rgb> PreviewImage::GenerateRGB(const uint8_t* value_8,
|
||||
|| (settings.show_user_mask && (mask[i] == MaskUsr))) {
|
||||
ret[i] = scale.Apply(ColorScaleSpecial::BadPixel);
|
||||
} else
|
||||
ret[i] = scale.Apply(value[i], 0.0, settings.saturation_value);;
|
||||
ret[i] = scale.Apply(value[i], background, foreground);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -197,15 +229,13 @@ void PreviewImage::Configure() {
|
||||
ypixel = 0;
|
||||
}
|
||||
|
||||
std::vector<rgb> PreviewImage::GenerateRGB(const PreviewImageSettings &settings,
|
||||
const CompressedImage &xray_image,
|
||||
const std::vector<SpotToSave> &in_spots) const {
|
||||
std::vector<rgb> v(xray_image.GetWidth() * xray_image.GetHeight());
|
||||
if (xray_image.GetUncompressedSize() == 0)
|
||||
std::vector<rgb> PreviewImage::GenerateRGB(const PreviewImageSettings &settings, const DataMessage &msg) const {
|
||||
std::vector<rgb> v(msg.image.GetWidth() * msg.image.GetHeight());
|
||||
if (msg.image.GetUncompressedSize() == 0)
|
||||
return {};
|
||||
|
||||
std::vector<uint8_t> tmp;
|
||||
const uint8_t* image_ptr = xray_image.GetUncompressedPtr(tmp);
|
||||
const uint8_t* image_ptr = msg.image.GetUncompressedPtr(tmp);
|
||||
|
||||
{
|
||||
// JPEG compression is outside the critical loop protected by m
|
||||
@@ -214,37 +244,39 @@ std::vector<rgb> PreviewImage::GenerateRGB(const PreviewImageSettings &settings,
|
||||
ColorScale scale;
|
||||
scale.Select(settings.scale);
|
||||
|
||||
switch (xray_image.GetMode()) {
|
||||
switch (msg.image.GetMode()) {
|
||||
case CompressedImageMode::Int8:
|
||||
v = GenerateRGB<int8_t>(image_ptr, INT8_MIN, scale, settings);
|
||||
v = GenerateRGB<int8_t>(image_ptr, INT8_MIN, INT8_MAX, scale, settings);
|
||||
break;
|
||||
case CompressedImageMode::Int16:
|
||||
v = GenerateRGB<int16_t>(image_ptr, INT16_MIN, scale, settings);
|
||||
v = GenerateRGB<int16_t>(image_ptr, INT16_MIN, INT16_MAX, scale, settings);
|
||||
break;
|
||||
case CompressedImageMode::Int32:
|
||||
v = GenerateRGB<int32_t>(image_ptr, INT32_MIN, scale, settings);
|
||||
v = GenerateRGB<int32_t>(image_ptr, INT32_MIN, INT32_MAX, scale, settings);
|
||||
break;
|
||||
case CompressedImageMode::Uint8:
|
||||
v = GenerateRGB<uint8_t>(image_ptr,UINT8_MAX, scale, settings);
|
||||
v = GenerateRGB<uint8_t>(image_ptr,UINT8_MAX, UINT8_MAX, scale, settings);
|
||||
break;
|
||||
case CompressedImageMode::Uint16:
|
||||
v = GenerateRGB<uint16_t>(image_ptr,UINT16_MAX, scale, settings);
|
||||
v = GenerateRGB<uint16_t>(image_ptr,UINT16_MAX, UINT16_MAX, scale, settings);
|
||||
break;
|
||||
case CompressedImageMode::Uint32:
|
||||
v = GenerateRGB<uint32_t>(image_ptr,UINT16_MAX, scale, settings);
|
||||
v = GenerateRGB<uint32_t>(image_ptr,UINT32_MAX, UINT32_MAX, scale, settings);
|
||||
break;
|
||||
default:
|
||||
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Mode not supported");
|
||||
}
|
||||
|
||||
if (settings.show_spots)
|
||||
AddSpots(v, in_spots);
|
||||
AddSpots(v, msg.spots);
|
||||
|
||||
if (settings.show_roi)
|
||||
AddROI(v);
|
||||
|
||||
if (settings.resolution_ring)
|
||||
AddResolutionRing(v, settings.resolution_ring.value());
|
||||
else if (settings.show_res_est && msg.resolution_estimate)
|
||||
AddResolutionRing(v, msg.resolution_estimate.value());
|
||||
|
||||
if (settings.show_beam_center)
|
||||
AddBeamCenter(v);
|
||||
@@ -252,11 +284,9 @@ std::vector<rgb> PreviewImage::GenerateRGB(const PreviewImageSettings &settings,
|
||||
return v;
|
||||
}
|
||||
|
||||
std::string PreviewImage::GenerateImage(const PreviewImageSettings& settings,
|
||||
const CompressedImage& image,
|
||||
const std::vector<SpotToSave>& in_spots) const {
|
||||
auto v = GenerateRGB(settings, image, in_spots);
|
||||
CompressedImage rgb_image(v, image.GetWidth(), image.GetHeight());
|
||||
std::string PreviewImage::GenerateImage(const PreviewImageSettings& settings, const DataMessage &msg) const {
|
||||
auto v = GenerateRGB(settings, msg);
|
||||
CompressedImage rgb_image(v, msg.image.GetWidth(), msg.image.GetHeight());
|
||||
switch (settings.format) {
|
||||
case PreviewImageFormat::JPEG:
|
||||
return WriteJPEGToMem(rgb_image, settings.jpeg_quality);
|
||||
@@ -273,9 +303,7 @@ std::string PreviewImage::GenerateImage(const PreviewImageSettings &settings, co
|
||||
if (!cbor || !cbor->data_message)
|
||||
return {};
|
||||
|
||||
return GenerateImage(settings,
|
||||
cbor->data_message->image,
|
||||
cbor->data_message->spots);
|
||||
return GenerateImage(settings, *cbor->data_message);
|
||||
}
|
||||
|
||||
std::string PreviewImage::GenerateTIFF(const std::vector<uint8_t>& cbor_format) {
|
||||
|
||||
Reference in New Issue
Block a user