From: Inki Dae Date: Fri, 5 Apr 2024 03:32:57 +0000 (+0900) Subject: implement autozoom algorithm X-Git-Tag: accepted/tizen/unified/20240903.110722~76^2~3 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f07ecd8af6dc86ddf298176e865b5c5811c5a1dd;p=platform%2Fcore%2Fapi%2Fsingleo.git implement autozoom algorithm Implement autozoom algorithm. As for this, this patch introduces a new interface class, IPostprocessor, and its concrete class, Postprocessor for Autozoom service, which postprocesses a given camera preview image by emulating pysical camera zoom-in/out functions with zero latency. Signed-off-by: Inki Dae --- diff --git a/capi/singleo_native_capi.h b/capi/singleo_native_capi.h index e8b49d6..4322459 100644 --- a/capi/singleo_native_capi.h +++ b/capi/singleo_native_capi.h @@ -132,7 +132,7 @@ int singleo_service_add_input_image_file(singleo_service_h handle, const char *f * @pre Create a source handle by calling singleo_service_create() */ int singleo_service_add_input_rgb_data(singleo_service_h handle, const unsigned char *buffer, unsigned int width, - unsigned int height, unsigned long byte_per_pixel); + unsigned int height, unsigned long byte_per_pixel); /** * @internal diff --git a/services/auto_zoom/CMakeLists.txt b/services/auto_zoom/CMakeLists.txt index 5f1e03e..9f4aca1 100644 --- a/services/auto_zoom/CMakeLists.txt +++ b/services/auto_zoom/CMakeLists.txt @@ -1,6 +1,7 @@ set(SINGLEO_SERVICE_SOURCE_FILES ${SINGLEO_SERVICE_SOURCE_FILES} auto_zoom/src/AutoZoom.cpp + auto_zoom/src/Postprocessor.cpp ) LIST(APPEND SERVICE_LIBRARY_LIST singleo_inference) \ No newline at end of file diff --git a/services/auto_zoom/include/AutoZoom.h b/services/auto_zoom/include/AutoZoom.h index f062acd..cd65836 100644 --- a/services/auto_zoom/include/AutoZoom.h +++ b/services/auto_zoom/include/AutoZoom.h @@ -24,27 +24,23 @@ #include "IInputService.h" #include "SingleoInferenceTypes.h" #include "InputTypes.h" +#include "ServiceDataType.h" +#include "DataTypes.h" #include "AsyncManager.h" +#include "IPostprocessor.h" namespace singleo { namespace services { -struct AutoZoomResult : public BaseResultType { - AutoZoomResult() : BaseResultType(ServiceResultType::AUTO_ZOOM) - {} - unsigned int frame_number {}; - size_t num_of_result {}; - Rect rect; -}; - -enum class AutoZoomResultType { X, Y, WIDTH, HEIGHT }; - +namespace autozoom +{ class AutoZoom : public IService { private: std::unique_ptr _inference_service; std::unique_ptr _input_service; + std::unique_ptr _postprocessor; SingleoInputManager _input_image_data; AutoZoomResult _result {}; std::map _result_keys = { { "X", AutoZoomResultType::X }, @@ -90,8 +86,13 @@ public: { return _inference_service; } + std::unique_ptr &getPostprocessor() + { + return _postprocessor; + } }; +} // autozoom } // service } // singleo diff --git a/services/auto_zoom/include/DataTypes.h b/services/auto_zoom/include/DataTypes.h new file mode 100644 index 0000000..9918322 --- /dev/null +++ b/services/auto_zoom/include/DataTypes.h @@ -0,0 +1,44 @@ +/** + * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __DATA_TYPES_H__ +#define __DATA_TYPES_H__ + +#include +#include "SingleoCommonTypes.h" +#include "ServiceDataType.h" + +namespace singleo +{ +namespace services +{ +namespace autozoom +{ +enum class AutoZoomResultType { X, Y, WIDTH, HEIGHT }; + +struct AutoZoomResult : public ServiceBaseResultType { + AutoZoomResult() : ServiceBaseResultType(ServiceResultType::AUTO_ZOOM) + {} + unsigned int frame_number {}; + unsigned int num_of_objects {}; + Rect merged_rect; +}; + +} +} +} + +#endif \ No newline at end of file diff --git a/services/auto_zoom/include/Postprocessor.h b/services/auto_zoom/include/Postprocessor.h new file mode 100644 index 0000000..59124c5 --- /dev/null +++ b/services/auto_zoom/include/Postprocessor.h @@ -0,0 +1,81 @@ +/** + * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __POSTPROCESSOR_H__ +#define __POSTPROCESSOR_H__ + +#include +#include +#include + +#include "IPostprocessor.h" +#include "SingleoCommonTypes.h" +#include "ServiceDataType.h" +#include "DataTypes.h" + +namespace singleo +{ +namespace services +{ +namespace autozoom +{ +enum class AutozoomState { NONE, IN, OUT, DETECT }; + +class Postprocessor : public IPostprocessor +{ +private: + AutoZoomResult _result; + cv::Mat _cv_image; + ImageDataType _image_data; + + AutozoomState _state { AutozoomState::DETECT }; + Rect _zoom_rect; + Rect _zoom_in_rect; + std::mutex _mutex; + unsigned int _loss_cnt {}; + double _zoom_scale { 1.0 }; + // TODO. default const values to below members will be loaded from json file later. + const double _min_zoom_scale { 1.0 }; + const double _max_zoom_scale { 2.0 }; + const double _zoom_in_step { 0.02 }; + const double _zoom_out_step { 0.1 }; + const unsigned int _max_loss_cnt { 60 }; + bool _is_working { false }; + bool _detected { false }; + cv::Point2f _center {}; + + AutozoomState getNextState(); + void adjustPreview(cv::Mat &image, cv::Mat &cv_result); + +public: + Postprocessor() = default; + virtual ~Postprocessor() = default; + + void addInput(ServiceBaseResultType &data) override; + BaseDataType &getOutput() override; + BaseDataType &getOutput(BaseDataType &data) override; + + bool isWorking() override + { + return _is_working; + } +}; + +} +} +} + +#endif \ No newline at end of file diff --git a/services/auto_zoom/src/AutoZoom.cpp b/services/auto_zoom/src/AutoZoom.cpp index 33aad0a..34a7bc4 100644 --- a/services/auto_zoom/src/AutoZoom.cpp +++ b/services/auto_zoom/src/AutoZoom.cpp @@ -14,6 +14,7 @@ * limitations under the License. */ +#include #include "SingleoException.h" #include "AutoZoom.h" #include "InferenceServiceDefault.h" @@ -22,6 +23,7 @@ #include "ServiceFactory.h" #include "InputCamera.h" #include "InputTypes.h" +#include "Postprocessor.h" using namespace std; using namespace singleo::inference; @@ -32,6 +34,8 @@ namespace singleo { namespace services { +namespace autozoom +{ REGISTER_SERVICE(AutoZoom) AutoZoom::AutoZoom(InputConfigBase &config) @@ -51,6 +55,7 @@ AutoZoom::AutoZoom(InputConfigBase &config) _inference_service->configure(); _inference_service->prepare(); + _postprocessor = make_unique(); } AutoZoom::~AutoZoom() @@ -62,6 +67,7 @@ AutoZoom::~AutoZoom() void AutoZoom::inputServiceCb(BaseDataType &data, void *user_data) { auto auto_zoom = static_cast(user_data); + ImagePreprocessor preprocessor(data); ImageDataType preprocessed = dynamic_cast(preprocessor.getData()); ImageDataType copied = preprocessed; @@ -72,13 +78,20 @@ void AutoZoom::inputServiceCb(BaseDataType &data, void *user_data) copied.ptr = new unsigned char[buffer_size]; memcpy(copied.ptr, preprocessed.ptr, buffer_size); - // Make sure to release copied buffer if incoming queue isn't empty so skipped pushing the buffer. - if (auto_zoom->getAsyncManager()->pushInput(copied) != SINGLEO_ERROR_NONE) { - if (auto_zoom->_user_cb) + if (auto_zoom->_user_cb) { + // if postprocessor isn't in progress, postprocess current camera preview image. + if (!auto_zoom->getPostprocessor()->isWorking()) { + ImageDataType zoom_data = dynamic_cast(auto_zoom->getPostprocessor()->getOutput(copied)); + + auto_zoom->_user_cb(zoom_data.ptr, zoom_data.width, zoom_data.height, zoom_data.byte_per_pixel, auto_zoom->_user_data); + } else { auto_zoom->_user_cb(copied.ptr, copied.width, copied.height, copied.byte_per_pixel, auto_zoom->_user_data); + } + } + // Make sure to release copied buffer if incoming queue isn't empty so skipped pushing the buffer. + if (auto_zoom->getAsyncManager()->pushInput(copied) != SINGLEO_ERROR_NONE) delete copied.ptr; - } } bool AutoZoom::isKeyValid(std::string key) @@ -163,48 +176,68 @@ void AutoZoom::updateResult(BaseDataType &in_data) { auto &output_data = _inference_service->result(); unsigned int frame_number = output_data.getFrameNumber(); - Rect rect; - size_t result_cnt {}; + AutoZoomResult autozoom_result; if (_task_type == TaskType::OBJECT_DETECTION) { const vector &result = output_data.getOdResult(); - if (!result.empty()) { - rect = result[0].rect; - result_cnt = result.size(); + autozoom_result.num_of_objects = result.size(); + for (size_t idx = 0; idx < result.size(); ++idx) { + SINGLEO_LOGD("%dx%d ~ %dx%d", result[idx].rect.left, result[idx].rect.top, result[idx].rect.right, + result[idx].rect.bottom); + + if (idx == 0) { + autozoom_result.merged_rect = result[idx].rect; + continue; + } + autozoom_result.merged_rect.left = min(result[idx].rect.left, autozoom_result.merged_rect.left); + autozoom_result.merged_rect.top = min(result[idx].rect.top, autozoom_result.merged_rect.top); + autozoom_result.merged_rect.right = max(result[idx].rect.right, autozoom_result.merged_rect.right); + autozoom_result.merged_rect.bottom = max(result[idx].rect.bottom, autozoom_result.merged_rect.bottom); } } else { const vector &result = output_data.getFdResult(); - if (!result.empty()) { - rect = result[0].rect; - result_cnt = result.size(); + autozoom_result.num_of_objects = result.size(); + for (size_t idx = 0; idx < result.size(); ++idx) { + SINGLEO_LOGD("%dx%d ~ %dx%d", result[idx].rect.left, result[idx].rect.top, result[idx].rect.right, + result[idx].rect.bottom); + + if (idx == 0) { + autozoom_result.merged_rect = result[idx].rect; + continue; + } + autozoom_result.merged_rect.left = min(result[idx].rect.left, autozoom_result.merged_rect.left); + autozoom_result.merged_rect.top = min(result[idx].rect.top, autozoom_result.merged_rect.top); + autozoom_result.merged_rect.right = max(result[idx].rect.right, autozoom_result.merged_rect.right); + autozoom_result.merged_rect.bottom = max(result[idx].rect.bottom, autozoom_result.merged_rect.bottom); } } + autozoom_result.frame_number = frame_number; + // TODO. implement Postprocessor which calculates Autozoom position using above 'result' vector. - SINGLEO_LOGD("result cnt = %zu", result_cnt); - _result.num_of_result = result_cnt; + SINGLEO_LOGD("detected object count = %zu", autozoom_result.num_of_objects); - if (result_cnt == 0) { + if (autozoom_result.num_of_objects == 0) { SINGLEO_LOGW("No detected objects."); return; } - // TODO. Temparary code for test. - _result.rect = rect; - _result.frame_number = frame_number; - if (_async_mode) - _async_manager->pushOutput(_result); + _async_manager->pushOutput(autozoom_result); + else + _result = autozoom_result; } void AutoZoom::getResultCnt(unsigned int *cnt) { - if (_async_mode) + if (_async_mode) { _result = _async_manager->popOutput(); + _postprocessor->addInput(_result); + } // TODO. Temparary code. - *cnt = static_cast(_result.num_of_result); + *cnt = static_cast(_result.num_of_objects); } void AutoZoom::getResultInt(unsigned int idx, std::string key, unsigned int *value) @@ -218,16 +251,16 @@ void AutoZoom::getResultInt(unsigned int idx, std::string key, unsigned int *val switch (_result_keys[key]) { case AutoZoomResultType::X: - *value = _result.rect.left; + *value = _result.merged_rect.left; break; case AutoZoomResultType::Y: - *value = _result.rect.top; + *value = _result.merged_rect.top; break; case AutoZoomResultType::WIDTH: - *value = _result.rect.right; + *value = _result.merged_rect.right; break; case AutoZoomResultType::HEIGHT: - *value = _result.rect.bottom; + *value = _result.merged_rect.bottom; break; } } @@ -246,3 +279,4 @@ void AutoZoom::unregisterUserCallback() } } +} diff --git a/services/auto_zoom/src/Postprocessor.cpp b/services/auto_zoom/src/Postprocessor.cpp new file mode 100644 index 0000000..c739108 --- /dev/null +++ b/services/auto_zoom/src/Postprocessor.cpp @@ -0,0 +1,159 @@ +/** + * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "SingleoException.h" +#include "SingleoLog.h" +#include "Postprocessor.h" + +using namespace std; +using namespace singleo::exception; + +namespace singleo +{ +namespace services +{ +namespace autozoom +{ +void Postprocessor::addInput(ServiceBaseResultType &data) +{ + if (data._result_type != ServiceResultType::AUTO_ZOOM) { + SINGLEO_LOGE("invalid result data type."); + throw InvalidParameter("invalid result data type."); + } + + std::lock_guard lock(_mutex); + AutoZoomResult &result = dynamic_cast(data); + + // Update detected rect only in case that current state is DETECT. + if (_state != AutozoomState::DETECT) + return; + + _result = result; + _detected = true; + _loss_cnt = 0; +} + +AutozoomState Postprocessor::getNextState() +{ + const int min_threshold = 70.0, max_threshold = 150.0; + double w_size = static_cast(_result.merged_rect.right - _result.merged_rect.left); + + if (w_size * _zoom_scale <= min_threshold) + return AutozoomState::IN; + + if (w_size * _zoom_scale >= max_threshold) + return AutozoomState::OUT; + + return AutozoomState::DETECT; +} + +void Postprocessor::adjustPreview(cv::Mat &image, cv::Mat &cv_result) +{ + // adjust the zoom scale based on the current state + switch (_state) { + case AutozoomState::IN: + if (_zoom_scale < _max_zoom_scale) + _zoom_scale += _zoom_in_step; + + break; + + case AutozoomState::OUT: + if (_zoom_scale > _min_zoom_scale) + _zoom_scale -= _zoom_out_step; + + break; + + default: + break; + } + + // reset the state and detected flag if the zoom scale has reached its limit + if (_zoom_scale <= _min_zoom_scale || _zoom_scale >= _max_zoom_scale) { + _state = AutozoomState::DETECT; + _detected = false; + } + + // Create a rotation matrix for scaling without rotation + cv::Mat rot_mat = cv::getRotationMatrix2D(_center, 0, _zoom_scale); + + // Apply the transformation + cv::warpAffine(image, cv_result, rot_mat, image.size()); +} + +BaseDataType &Postprocessor::getOutput() +{ + throw InvalidOperation("Not supported."); +} + +BaseDataType &Postprocessor::getOutput(BaseDataType &data) +{ + if (data._data_type != DataType::IMAGE) { + SINGLEO_LOGE("invalid data type."); + throw InvalidParameter("invalid data type."); + } + + ImageDataType &image_data = dynamic_cast(data); + + cv::Mat cv_image(cv::Size(image_data.width, image_data.height), CV_MAKETYPE(CV_8U, 3), image_data.ptr); + cv::cvtColor(cv_image, cv_image, cv::COLOR_BGR2RGBA); + + std::lock_guard lock(_mutex); + _is_working = true; + + // If detection loss has happended for 2 seconds - 60 is 30fps * 2 - while in maximum zoom-in + // then change the current state to zoom-out. + // Ps. if detected then loss_cnt will be rested to 0. + if (_zoom_scale >= _max_zoom_scale && _state == AutozoomState::DETECT) { + if (++_loss_cnt > _max_loss_cnt) { + _loss_cnt = 0; + _state = AutozoomState::OUT; + } + } + + if (_state == AutozoomState::DETECT && _detected) { + AutozoomState next_state = getNextState(); + + // If next state is zoom in then copy zoom_in_rect so that this rect can be used for zoom out. + if (next_state == AutozoomState::IN) { + _zoom_rect = _result.merged_rect; + _zoom_in_rect = _zoom_rect; + _center.x = static_cast(_zoom_rect.left + _zoom_rect.right) / 2.0; + _center.y = static_cast(_zoom_rect.bottom + _zoom_rect.top) / 2.0; + _state = AutozoomState::IN; + } + + // If next state is zoom out then do zoom-out with previous zoom-in rect. + if (next_state == AutozoomState::OUT) { + _center.x = static_cast(_zoom_in_rect.left + _zoom_in_rect.right) / 2.0; + _center.y = static_cast(_zoom_in_rect.bottom + _zoom_in_rect.top) / 2.0; + _state = AutozoomState::OUT; + } + } + + adjustPreview(cv_image, _cv_image); + + _is_working = false; + + _image_data.width = _cv_image.cols; + _image_data.height = _cv_image.rows; + _image_data.byte_per_pixel = _cv_image.channels(); + _image_data.ptr = _cv_image.data; + + return _image_data; +} +} +} +} \ No newline at end of file diff --git a/services/common/include/IPostprocessor.h b/services/common/include/IPostprocessor.h new file mode 100644 index 0000000..a58f4a8 --- /dev/null +++ b/services/common/include/IPostprocessor.h @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __IPOSTPROCESSOR_H__ +#define __IPOSTPROCESSOR_H__ + +#include "SingleoCommonTypes.h" +#include "ServiceDataType.h" + +namespace singleo +{ +namespace services +{ +class IPostprocessor +{ +public: + virtual ~IPostprocessor() {}; + + virtual void addInput(ServiceBaseResultType &data) = 0; + virtual BaseDataType &getOutput() = 0; + virtual BaseDataType &getOutput(BaseDataType &data) = 0; + virtual bool isWorking() = 0; +}; + +} +} + +#endif \ No newline at end of file diff --git a/services/common/include/IService.h b/services/common/include/IService.h index f5bdf51..de774ac 100644 --- a/services/common/include/IService.h +++ b/services/common/include/IService.h @@ -21,7 +21,6 @@ #include "SingleoCommonTypes.h" #include "IPreprocessor.h" -#include "InputDataType.h" namespace singleo { diff --git a/services/common/include/ImagePreprocessor.h b/services/common/include/ImagePreprocessor.h index 8ba3dcf..ef7458f 100644 --- a/services/common/include/ImagePreprocessor.h +++ b/services/common/include/ImagePreprocessor.h @@ -23,7 +23,6 @@ #include #include "IPreprocessor.h" -#include "InputDataType.h" namespace singleo { diff --git a/services/common/include/InputDataType.h b/services/common/include/InputDataType.h deleted file mode 100644 index 2bcacd9..0000000 --- a/services/common/include/InputDataType.h +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __INPUT_DATA_TYPE_H__ -#define __INPUT_DATA_TYPE_H__ - -#include "SingleoCommonTypes.h" - -namespace singleo -{ -namespace services -{ -// TODO - -enum class ServiceResultType { NONE, AUTO_ZOOM }; - -struct BaseResultType { - ServiceResultType _result_type { ServiceResultType::NONE }; - BaseResultType(ServiceResultType result_type) : _result_type(result_type) - {} - virtual ~BaseResultType() - {} -}; - -} -} - -#endif \ No newline at end of file diff --git a/services/common/include/ServiceDataType.h b/services/common/include/ServiceDataType.h new file mode 100644 index 0000000..b992d4d --- /dev/null +++ b/services/common/include/ServiceDataType.h @@ -0,0 +1,42 @@ +/** + * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __INPUT_DATA_TYPE_H__ +#define __INPUT_DATA_TYPE_H__ + +#include +#include "SingleoCommonTypes.h" + +namespace singleo +{ +namespace services +{ +// TODO + +enum class ServiceResultType { NONE, AUTO_ZOOM }; + +struct ServiceBaseResultType { + ServiceResultType _result_type { ServiceResultType::NONE }; + ServiceBaseResultType(ServiceResultType result_type) : _result_type(result_type) + {} + virtual ~ServiceBaseResultType() + {} +}; + +} +} + +#endif \ No newline at end of file diff --git a/services/singleo_native_capi.cpp b/services/singleo_native_capi.cpp index 2786d9b..1595d93 100644 --- a/services/singleo_native_capi.cpp +++ b/services/singleo_native_capi.cpp @@ -83,7 +83,7 @@ int singleo_service_add_input_image_file(singleo_service_h handle, const char *f } int singleo_service_add_input_rgb_data(singleo_service_h handle, const unsigned char *buffer, unsigned int width, - unsigned int height, unsigned long byte_per_pixel) + unsigned int height, unsigned long byte_per_pixel) { try { auto context = static_cast(handle); diff --git a/test/services/test_autozoom_on_screen.cpp b/test/services/test_autozoom_on_screen.cpp index 15802cb..71da41a 100644 --- a/test/services/test_autozoom_on_screen.cpp +++ b/test/services/test_autozoom_on_screen.cpp @@ -31,24 +31,10 @@ using namespace testing; using namespace std; -struct Rect { - int left; - int top; - int right; - int bottom; -}; - -struct Rgb { - int r; - int g; - int b; -}; +enum class AutozoomState { NONE, IN, IN_DONE, OUT, OUT_DONE, DETECT }; struct Context { singleo_service_h handle {}; - std::mutex mutex; - Rect rect {}; - Rgb rgb {}; }; void autozoom_callback(void *user_data) @@ -65,29 +51,9 @@ void autozoom_callback(void *user_data) if (ret != SINGLEO_ERROR_NONE) break; - ASSERT_EQ(ret, SINGLEO_ERROR_NONE); - - for (unsigned int idx = 0; idx < cnt; ++idx) { - unsigned int x, y, w, h; - - ret = singleo_service_get_result_int(handle, idx, "x", &x); - ASSERT_EQ(ret, SINGLEO_ERROR_NONE); - ret = singleo_service_get_result_int(handle, idx, "y", &y); - ASSERT_EQ(ret, SINGLEO_ERROR_NONE); - ret = singleo_service_get_result_int(handle, idx, "width", &w); - ASSERT_EQ(ret, SINGLEO_ERROR_NONE); - ret = singleo_service_get_result_int(handle, idx, "height", &h); - ASSERT_EQ(ret, SINGLEO_ERROR_NONE); - - cout << x << " x " << y << " ~ " << w << " x " << h << endl; + cout << "cnt = " << cnt << " frame number = " << frame_number << endl; - context->mutex.lock(); - context->rect.left = x; - context->rect.top = y; - context->rect.bottom = h; - context->rect.right = w; - context->mutex.unlock(); - } + ASSERT_EQ(ret, SINGLEO_ERROR_NONE); if (++frame_number > 500 && cnt > 0) is_loop_exit = true; @@ -98,34 +64,16 @@ void user_callback(unsigned char *buffer, unsigned int width, unsigned int heigh void *user_data) { Context *context = static_cast(user_data); - Rgb *rgb = &context->rgb; - - context->mutex.lock(); - Rect rect = context->rect; - context->mutex.unlock(); - - cv::Mat cv_image(cv::Size(width, height), CV_MAKETYPE(CV_8U, 3), buffer); - cv::Point leftTop(rect.left, rect.top); - cv::Point rightBottom(rect.right, rect.bottom); + cv::Mat result(cv::Size(width, height), CV_MAKETYPE(CV_8U, 4), buffer); - cv::cvtColor(cv_image, cv_image, cv::COLOR_BGR2RGBA); - cv::rectangle(cv_image, cv::Rect(leftTop, rightBottom), cv::Scalar(rgb->r, rgb->g, rgb->b)); - - cv::Mat resized_image(cv::Size(1600, 900), CV_8UC4, cv::Scalar(0, 0, 0, 0)); - cv::resize(cv_image, resized_image, resized_image.size()); - - singleo_util_visualizer_2d(resized_image, NULL); + singleo_util_visualizer_2d(result, NULL); } TEST(AutoZoomAsyncOnScreenTest, InferenceRequestWithCameraInputFeedShouldBeOk) { Context context {}; - context.rgb.r = 255; - context.rgb.g = 0; - context.rgb.b = 0; - int ret = singleo_service_create("service=auto_zoom, input_feed=camera, camera_id=0, fps=30, async=1", &context.handle); ASSERT_EQ(ret, SINGLEO_ERROR_NONE);