• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

paulmthompson / WhiskerToolbox / 17402643318

02 Sep 2025 11:53AM UTC coverage: 71.394% (-0.3%) from 71.68%
17402643318

push

github

paulmthompson
remove unnecessary files

31766 of 44494 relevant lines covered (71.39%)

1386.13 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

1.22
/src/DataManager/Media/Image_Data.cpp
1

2
#include "Media/Image_Data.hpp"
3

4
#include "utils/string_manip.hpp"
5

6
#include <opencv2/core/core.hpp>
7
#include <opencv2/imgcodecs.hpp>
8
#include <opencv2/imgproc.hpp>
9

10
#include <cstddef>
11
#include <iostream>
12
#include <set>
13

14

15
ImageData::ImageData() = default;
4✔
16

17
void ImageData::doLoadMedia(std::string const & dir_name) {
×
18

19
    auto file_extensions = std::set<std::string>{".png", ".jpg"};
×
20

21
    for (auto const & entry: std::filesystem::directory_iterator(dir_name)) {
×
22
        if (file_extensions.count(entry.path().extension().string())) {
×
23
            _image_paths.push_back(dir_name / entry.path());
×
24
        }
25
    }
×
26

27
    if (_image_paths.empty()) {
×
28
        std::cout << "Warning: No images found in directory with matching extensions ";
×
29
        for (auto const & i: file_extensions) {
×
30
            std::cout << i << " ";
×
31
        }
32
        std::cout << std::endl;
×
33
    }
34

35
    setTotalFrameCount(static_cast<int>(_image_paths.size()));
×
36
}
×
37

38
cv::Mat convert_to_display_format(cv::Mat & image, ImageData::DisplayFormat format, ImageData::BitDepth& detected_depth) {
×
39
    cv::Mat converted_image;
×
40
    
41
    // Detect bit depth from input image
42
    if (image.depth() == CV_16U || image.depth() == CV_32F) {
×
43
        detected_depth = ImageData::BitDepth::Bit32;
×
44
    } else {
45
        detected_depth = ImageData::BitDepth::Bit8;
×
46
    }
47
    
48
    if (format == ImageData::DisplayFormat::Gray) {
×
49
        if (image.channels() > 1) {
×
50
            cv::cvtColor(image, converted_image, cv::COLOR_BGR2GRAY);
×
51
        } else {
52
            converted_image = image.clone();
×
53
        }
54
        
55
        // Normalize to 0-255 range based on bit depth
56
        if (detected_depth == ImageData::BitDepth::Bit32) {
×
57
            // Convert to float and normalize
58
            if (converted_image.depth() == CV_16U) {
×
59
                // Properly scale 16-bit to 0-255 range using temporary variable
60
                cv::Mat temp_float;
×
61
                converted_image.convertTo(temp_float, CV_32F, 255.0/65535.0);
×
62
                converted_image = temp_float;
×
63
            } else if (converted_image.depth() != CV_32F) {
×
64
                cv::Mat temp_float;
×
65
                converted_image.convertTo(temp_float, CV_32F);
×
66
                converted_image = temp_float;
×
67
            }
×
68
            // Only normalize if the data doesn't appear to be already in 0-255 range
69
            double min_val, max_val;
×
70
            cv::minMaxLoc(converted_image, &min_val, &max_val);
×
71
            if (max_val > 255.0 || min_val < 0.0) {
×
72
                cv::Mat temp_normalized;
×
73
                cv::normalize(converted_image, temp_normalized, 0.0, 255.0, cv::NORM_MINMAX, CV_32F);
×
74
                converted_image = temp_normalized;
×
75
            }
×
76
        } else {
77
            // Ensure 8-bit output
78
            if (converted_image.depth() != CV_8U) {
×
79
                converted_image.convertTo(converted_image, CV_8U);
×
80
            }
81
        }
82
    } else if (format == ImageData::DisplayFormat::Color) {
×
83
        if (image.channels() == 1) {
×
84
            cv::cvtColor(image, converted_image, cv::COLOR_GRAY2BGRA);
×
85
        } else {
86
            cv::cvtColor(image, converted_image, cv::COLOR_BGR2BGRA);
×
87
        }
88
        
89
        // Color images are typically kept as 8-bit for now
90
        if (converted_image.depth() != CV_8U) {
×
91
            converted_image.convertTo(converted_image, CV_8U);
×
92
        }
93
        detected_depth = ImageData::BitDepth::Bit8;
×
94
    }
95
    return converted_image;
×
96
}
×
97

98
void ImageData::doLoadFrame(int frame_id) {
×
99

100
    if (frame_id > _image_paths.size()) {
×
101
        std::cout << "Error: Requested frame ID is larger than the number of frames in Media Data" << std::endl;
×
102
        return;
×
103
    }
104

105
    // Load image with unchanged depth to detect bit depth
106
    auto loaded_image = cv::imread(_image_paths[frame_id].string(), cv::IMREAD_UNCHANGED);
×
107

108
    updateHeight(loaded_image.rows);
×
109
    updateWidth(loaded_image.cols);
×
110

111
    BitDepth detected_depth;
×
112
    auto converted_image = convert_to_display_format(loaded_image, this->getFormat(), detected_depth);
×
113
    
114
    setBitDepth(detected_depth);
×
115

116
    size_t const num_bytes = converted_image.total() * converted_image.elemSize();
×
117
    
118
    if (detected_depth == BitDepth::Bit32) {
×
119
        // Data is float, use 32-bit setRawData
120
        auto* float_ptr = reinterpret_cast<float*>(converted_image.data);
×
121
        this->setRawData(MediaStorage::ImageData32(float_ptr, float_ptr + converted_image.total()));
×
122
    } else {
123
        // Data is uint8_t, use 8-bit setRawData
124
        auto* uint8_ptr = static_cast<uint8_t*>(converted_image.data);
×
125
        this->setRawData(MediaStorage::ImageData8(uint8_ptr, uint8_ptr + num_bytes));
×
126
    }
127
}
×
128

129
std::string ImageData::GetFrameID(int frame_id) const {
×
130
    return _image_paths[frame_id].filename().string();
×
131
}
132

133
int ImageData::getFrameIndexFromNumber(int frame_id) {
×
134
    for (std::size_t i = 0; i < _image_paths.size(); i++) {
×
135
        auto image_frame_id = extract_numbers_from_string(_image_paths[i].filename().string());
×
136
        if (std::stoi(image_frame_id) == frame_id) {
×
137
            return static_cast<int>(i);
×
138
        }
139
    }
×
140
    std::cout << "No matching frame found for requested ID" << std::endl;
×
141
    return 0;
×
142
}
143

144
void ImageData::setImagePaths(std::vector<std::filesystem::path> const & image_paths) {
×
145
    _image_paths = image_paths;
×
146
    setTotalFrameCount(static_cast<int>(_image_paths.size()));
×
147
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc