implement autozoom algorithm
authorInki Dae <inki.dae@samsung.com>
Fri, 5 Apr 2024 03:32:57 +0000 (12:32 +0900)
committerInki Dae <inki.dae@samsung.com>
Fri, 5 Apr 2024 05:33:20 +0000 (14:33 +0900)
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 <inki.dae@samsung.com>
14 files changed:
capi/singleo_native_capi.h
services/auto_zoom/CMakeLists.txt
services/auto_zoom/include/AutoZoom.h
services/auto_zoom/include/DataTypes.h [new file with mode: 0644]
services/auto_zoom/include/Postprocessor.h [new file with mode: 0644]
services/auto_zoom/src/AutoZoom.cpp
services/auto_zoom/src/Postprocessor.cpp [new file with mode: 0644]
services/common/include/IPostprocessor.h [new file with mode: 0644]
services/common/include/IService.h
services/common/include/ImagePreprocessor.h
services/common/include/InputDataType.h [deleted file]
services/common/include/ServiceDataType.h [new file with mode: 0644]
services/singleo_native_capi.cpp
test/services/test_autozoom_on_screen.cpp

index e8b49d68c1079c77758350f6b33ce06277cf7c02..43224596312a761d33e0940d8355383989d01f73 100644 (file)
@@ -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
index 5f1e03e5f05688db548b404285b880ef220f7a66..9f4aca106657b982426195c5eff0587d453975c0 100644 (file)
@@ -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
index f062acda9e0b04ba26615592d1d48b8c78b098c8..cd65836409d0c41cc7105592eaad1207bef5ea1e 100644 (file)
 #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<singleo::inference::IInferenceServiceInterface> _inference_service;
        std::unique_ptr<singleo::input::IInputService> _input_service;
+       std::unique_ptr<IPostprocessor> _postprocessor;
        SingleoInputManager _input_image_data;
        AutoZoomResult _result {};
        std::map<std::string, AutoZoomResultType> _result_keys = { { "X", AutoZoomResultType::X },
@@ -90,8 +86,13 @@ public:
        {
                return _inference_service;
        }
+       std::unique_ptr<IPostprocessor> &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 (file)
index 0000000..9918322
--- /dev/null
@@ -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 <vector>
+#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 (file)
index 0000000..59124c5
--- /dev/null
@@ -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 <vector>
+#include <opencv2/opencv.hpp>
+#include <mutex>
+
+#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
index 33aad0aeb3e7c31cc69b4cb8f91d07c779515ffd..34a7bc4b56b6eb8a1b1158838b2038ac5af125d3 100644 (file)
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <algorithm>
 #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<Postprocessor>();
 }
 
 AutoZoom::~AutoZoom()
@@ -62,6 +67,7 @@ AutoZoom::~AutoZoom()
 void AutoZoom::inputServiceCb(BaseDataType &data, void *user_data)
 {
        auto auto_zoom = static_cast<AutoZoom *>(user_data);
+
        ImagePreprocessor preprocessor(data);
        ImageDataType preprocessed = dynamic_cast<ImageDataType &>(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<ImageDataType &>(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<OdResultType> &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<FdResultType> &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<unsigned int>(_result.num_of_result);
+       *cnt = static_cast<unsigned int>(_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 (file)
index 0000000..c739108
--- /dev/null
@@ -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<std::mutex> lock(_mutex);
+       AutoZoomResult &result = dynamic_cast<AutoZoomResult &>(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<double>(_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<ImageDataType &>(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<std::mutex> 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<double>(_zoom_rect.left + _zoom_rect.right) / 2.0;
+                       _center.y = static_cast<double>(_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<double>(_zoom_in_rect.left + _zoom_in_rect.right) / 2.0;
+                       _center.y = static_cast<double>(_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 (file)
index 0000000..a58f4a8
--- /dev/null
@@ -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
index f5bdf51e903dc96a787b2904e0217f91c8cc6bd0..de774ac8f823cdc779aa9b73c349b9ef1cc44a25 100644 (file)
@@ -21,7 +21,6 @@
 
 #include "SingleoCommonTypes.h"
 #include "IPreprocessor.h"
-#include "InputDataType.h"
 
 namespace singleo
 {
index 8ba3dcf2dc7f2172b5d8f002eed6df5c5fbcc78b..ef7458fe09a4e51ec732e4253c343f833787cabe 100644 (file)
@@ -23,7 +23,6 @@
 #include <opencv2/opencv.hpp>
 
 #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 (file)
index 2bcacd9..0000000
+++ /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 (file)
index 0000000..b992d4d
--- /dev/null
@@ -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 <vector>
+#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
index 2786d9bdfcb48f9608b085aed857bbe1bf046920..1595d9324bfcf9482f450d41f09fca3c10fff5ae 100644 (file)
@@ -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<Context *>(handle);
index 15802cbef1df8e74d1ac2a81086ca5cab9e105b5..71da41a18369438b7a2c193f7e58f6a91877d10b 100644 (file)
 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<Context *>(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);