2 #include <opencv2/imgproc.hpp>
9 return std::abs(1.f - value) <= 0.00001f;
17 "No stream configuration available!",
21 std::vector<std::pair<float, int>> matchingSizes;
28 if (
config.widthPix >= requiredSize.width &&
29 config.heightPix >= requiredSize.height)
32 float scaleFactor = 1.f;
34 if (((
float)requiredSize.width / (
float)requiredSize.height) > ((
float)
config.widthPix / (
float)
config.heightPix))
36 scaleFactor = (float)requiredSize.width / (
float)
config.widthPix;
37 float heightScaled =
config.heightPix * scaleFactor;
38 crop += heightScaled - requiredSize.height;
39 crop += (float)
config.widthPix * scaleFactor - (
float)requiredSize.width;
43 scaleFactor = (float)requiredSize.height / (
float)
config.heightPix;
44 float widthScaled =
config.widthPix * scaleFactor;
45 crop += widthScaled - requiredSize.width;
46 crop += (float)
config.heightPix * scaleFactor - (
float)requiredSize.height;
49 float cropScaleScore = crop;
52 matchingSizes.push_back(std::make_pair(cropScaleScore, i));
56 std::sort(matchingSizes.begin(), matchingSizes.end());
58 return matchingSizes.front().second;
64 {
return comp.
deviceId() == deviceId; }) != end();
70 {
return comp.
facing() == facing; }) != end();
76 {
return comp.
deviceId() == deviceId; });
77 if (camPropsIt != end())
88 std::pair<const SENSCameraDeviceProps* const, const SENSCameraStreamConfig* const>
92 const int height)
const
106 float horizFov = -1.f;
111 float fovScore = 0.f;
117 void print(
int idx)
const
119 std::stringstream ss;
120 ss <<
"Sort Elem " << idx;
121 ss <<
" fovV: " << horizFov;
122 ss <<
" fovV score: " << fovScore;
123 ss <<
" crop score: " << cropScore;
124 ss <<
" scale score " << scaleScore;
125 ss <<
" widthCropped: " << widthCropped;
126 ss <<
" heightCropped: " << heightCropped;
127 ss <<
" scale: " << scale;
128 ss <<
" width orig " << camChars->
streamConfigs()[streamConfigIdx].widthPix;
129 ss <<
" height orig " << camChars->
streamConfigs()[streamConfigIdx].heightPix;
130 Utils::log(
"SENSCaptureProps", ss.str().c_str());
133 auto printSortElems = [](
const std::vector<SortElem>& sortElems, std::string id)
135 std::cout <<
id << std::endl;
136 for (
int i = 0; i < sortElems.size(); ++i)
137 sortElems.at(i).print(i);
140 std::vector<SortElem> sortElems;
143 for (
auto itChars = begin(); itChars != end(); ++itChars)
145 if (facing != itChars->facing())
148 const auto& streams = itChars->streamConfigs();
149 float targetWidthDivHeight = (float)width / (
float)height;
151 for (
auto itStream = streams.begin(); itStream != streams.end(); ++itStream)
159 targetWidthDivHeight,
162 sortElem.widthCropped,
163 sortElem.heightCropped);
164 sortElem.scale = (float)width / (
float)sortElem.widthCropped;
166 if (sortElem.scale <= 1.f)
168 sortElem.camChars = &*itChars;
169 sortElem.streamConfigIdx = (int)(&*itStream - &*streams.begin());
170 sortElem.streamConfig = &*itStream;
171 if (
config.focalLengthPix > 0)
175 sortElem.widthCropped);
176 sortElem.fovScore =
std::abs(sortElem.horizFov - horizFov);
178 sortElem.cropScore = cropW + cropH;
181 sortElem.scaleScore = width * height;
183 sortElem.scaleScore = 0.f;
185 sortElems.push_back(sortElem);
190 if (sortElems.size())
193 std::sort(sortElems.begin(), sortElems.end(), [](
const SortElem& lhs,
const SortElem& rhs) ->
bool
194 { return lhs.fovScore < rhs.fovScore; });
198 std::vector<SortElem> closeFovSortElems;
199 float maxFovDiff = sortElems.front().fovScore + 3;
200 for (SortElem elem : sortElems)
202 if (elem.fovScore < maxFovDiff)
203 closeFovSortElems.push_back(elem);
207 std::sort(closeFovSortElems.begin(), closeFovSortElems.end(), [](
const SortElem& lhs,
const SortElem& rhs) ->
bool
208 { return lhs.scale > rhs.scale; });
211 const SortElem& bestSortElem = closeFovSortElems.front();
212 return std::make_pair(bestSortElem.camChars, bestSortElem.streamConfig);
216 return std::make_pair(
nullptr,
nullptr);
224 bool intrinsicsChanged)
235 l->onFrame(timePt, bgrImg.clone());
241 _frame = std::make_shared<SENSFrameBase>(timePt,
259 l->onCameraConfigChanged(
_config);
282 SENS_WARN(
"SENSBaseCamera latestFrame: Camera is not started!");
300 l->onCameraConfigChanged(
_config);
std::chrono::high_resolution_clock::time_point SENSTimePt
bool isEqualToOne(float value)
SENSCameraFacing
Definition of camera facing.
std::shared_ptr< SENSFrameBase > SENSFrameBasePtr
void registerListener(SENSCameraListener *listener) override
std::vector< SENSCameraListener * > _listeners
SENSCameraConfig _config
indicates what is currently running
SENSFrameBasePtr latestFrame() override
Get the latest captured frame. If no frame was captured the frame will be empty (null).
void unregisterListener(SENSCameraListener *listener) override
SENSFrameBasePtr _frame
current frame
std::atomic< bool > _started
flags if camera was started
void updateFrame(cv::Mat bgrImg, cv::Mat intrinsics, int width, int height, bool intrinsicsChanged)
std::mutex _listenerMutex
void processStart()
call from start function to do startup preprocessing
int findBestMatchingConfig(cv::Size requiredSize) const
const SENSCameraFacing & facing() const
std::vector< SENSCameraStreamConfig > _streamConfigs
const std::string & deviceId() const
const std::vector< SENSCameraStreamConfig > & streamConfigs() const
bool containsDeviceId(const std::string &deviceId) const
std::pair< const SENSCameraDeviceProps *const, const SENSCameraStreamConfig *const > findBestMatchingConfig(SENSCameraFacing facing, const float horizFov, const int width, const int height) const
Helper function to find a camera device and stream configuration with certain characteristics.
const SENSCameraDeviceProps * camPropsForDeviceId(const std::string &deviceId) const
bool supportsCameraFacing(const SENSCameraFacing &facing) const
Config config
The configuration set in App::run.
float calcFOVDegFromFocalLengthPix(const float focalLengthPix, const int imgLength)
bool calcCrop(cv::Size inputSize, float targetWdivH, int &cropW, int &cropH, int &width, int &height)
void log(const char *tag, const char *format,...)
logs a formatted string platform independently