summaryrefslogtreecommitdiff
path: root/mv_image
diff options
context:
space:
mode:
Diffstat (limited to 'mv_image')
-rw-r--r--mv_image/CMakeLists.txt8
-rw-r--r--mv_image/image/CMakeLists.txt33
-rw-r--r--mv_image/image/include/ImageConfig.h139
-rw-r--r--mv_image/image/include/ImageContourStabilizator.h102
-rw-r--r--mv_image/image/include/ImageMathUtil.h78
-rw-r--r--mv_image/image/include/ImageObject.h220
-rw-r--r--mv_image/image/include/ImageRecognizer.h116
-rw-r--r--mv_image/image/include/ImageTracker.h103
-rw-r--r--mv_image/image/include/ImageTrackingModel.h219
-rw-r--r--mv_image/image/include/mv_image_open.h561
-rw-r--r--mv_image/image/src/ImageConfig.cpp104
-rw-r--r--mv_image/image/src/ImageContourStabilizator.cpp300
-rw-r--r--mv_image/image/src/ImageMathUtil.cpp59
-rw-r--r--mv_image/image/src/ImageObject.cpp475
-rw-r--r--mv_image/image/src/ImageRecognizer.cpp312
-rw-r--r--mv_image/image/src/ImageTracker.cpp372
-rw-r--r--mv_image/image/src/ImageTrackingModel.cpp365
-rw-r--r--mv_image/image/src/mv_image_open.cpp784
-rw-r--r--mv_image/image_lic/CMakeLists.txt25
-rw-r--r--mv_image/image_lic/include/mv_image_lic.h564
-rw-r--r--mv_image/image_lic/src/mv_image_lic.c150
21 files changed, 5089 insertions, 0 deletions
diff --git a/mv_image/CMakeLists.txt b/mv_image/CMakeLists.txt
new file mode 100644
index 00000000..36d20373
--- /dev/null
+++ b/mv_image/CMakeLists.txt
@@ -0,0 +1,8 @@
+project(mv_image_port)
+cmake_minimum_required(VERSION 2.6)
+
+if(MEDIA_VISION_IMAGE_PORT)
+ add_subdirectory(${PROJECT_SOURCE_DIR}/image_lic) # Licensed port
+else()
+ add_subdirectory(${PROJECT_SOURCE_DIR}/image) # Open port
+endif()
diff --git a/mv_image/image/CMakeLists.txt b/mv_image/image/CMakeLists.txt
new file mode 100644
index 00000000..0269712f
--- /dev/null
+++ b/mv_image/image/CMakeLists.txt
@@ -0,0 +1,33 @@
+project(${MV_IMAGE_LIB_NAME})
+cmake_minimum_required(VERSION 2.6)
+
+set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_DEBUG _DEBUG)
+
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${LIB_INSTALL_DIR})
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${LIB_INSTALL_DIR})
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
+
+include_directories("${INC_DIR}")
+include_directories("${PROJECT_SOURCE_DIR}/include")
+include_directories("${PROJECT_SOURCE_DIR}/src")
+
+file(GLOB MV_IMAGE_INC_LIST "${PROJECT_SOURCE_DIR}/include/*.h")
+file(GLOB MV_IMAGE_SRC_LIST "${PROJECT_SOURCE_DIR}/src/*.cpp")
+
+find_package(OpenCV REQUIRED core highgui imgproc objdetect features2d calib3d)
+if(NOT OpenCV_FOUND)
+ message(SEND_ERROR "Failed to find OpenCV")
+ return()
+else()
+ include_directories(${OpenCV_INCLUDE_DIRS})
+endif()
+
+if(FORCED_STATIC_BUILD)
+ add_library(${PROJECT_NAME} STATIC ${MV_IMAGE_INC_LIST} ${MV_IMAGE_SRC_LIST})
+else()
+ add_library(${PROJECT_NAME} SHARED ${MV_IMAGE_INC_LIST} ${MV_IMAGE_SRC_LIST})
+endif()
+
+target_link_libraries(${PROJECT_NAME} ${MV_COMMON_LIB_NAME} ${OpenCV_LIBS})
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR})
diff --git a/mv_image/image/include/ImageConfig.h b/mv_image/image/include/ImageConfig.h
new file mode 100644
index 00000000..2d43430f
--- /dev/null
+++ b/mv_image/image/include/ImageConfig.h
@@ -0,0 +1,139 @@
+/**
+ * Copyright (c) 2015 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 __IMAGEUTIL_H__
+#define __IMAGEUTIL_H__
+
+#include <opencv/cv.h>
+
+/**
+ * @file ImageUtil.h
+ * @brief This file contains Image Module utility.
+ */
+
+namespace MediaVision
+{
+namespace Image
+{
+
+/**
+ * @brief Contains parameters for features extracting from image objects.
+ *
+ * @since_tizen 3.0
+ */
+struct FeaturesExtractingParams
+{
+ FeaturesExtractingParams(
+ double scaleFactor,
+ int maximumFeaturesNumber);
+
+ FeaturesExtractingParams();
+
+ double mScaleFactor; /**< Recognition scale factor for the ORB detector. */
+
+ int mMaximumFeaturesNumber; /**< Maximum number of features, which will be
+ extracted from object image. */
+};
+
+/**
+ * @brief Contains parameters for image objects recognition.
+ *
+ * @since_tizen 3.0
+ */
+struct RecognitionParams
+{
+ RecognitionParams(
+ int minMatchesNumber,
+ double requiredMatchesPart,
+ double allowableMatchesPartError);
+
+ RecognitionParams();
+
+ int mMinMatchesNumber; /**< The minimum matches number, which
+ will be taken into account for image objects recognition. */
+
+ double mRequiredMatchesPart; /**< The part of matches, which will be taken
+ into account for image objects recognition. Too low value will
+ result in unsustainable behavior, but effect of object overlapping
+ will be reduced. Value can be from 0 to 1.*/
+
+ double mAllowableMatchesPartError; /**< Allowable error of matches number. */
+};
+
+/**
+ * @brief Contains parameters for contour stabilization during tracking of image
+ * objects.
+ *
+ * @since_tizen 3.0
+ */
+struct StabilizationParams
+{
+ StabilizationParams(
+ int historyAmount,
+ double allowableShift,
+ double stabilizationSpeed,
+ double stabilizationAcceleration);
+
+ StabilizationParams();
+
+ int mHistoryAmount; /**< Number of previous recognition results, which
+ will influence the stabilization. */
+
+ double mAllowableShift; /**< Relative value of maximum shift per one frame,
+ which will be ignored by stabilization (relative to the object size
+ in the current frame). */
+
+ double mStabilizationSpeed; /**< Start speed with which the object will be
+ stabilized. */
+
+ double mStabilizationAcceleration; /**< Acceleration with which the object
+ will be stabilized. (relative to the distance from current location
+ to stabilized location). Value can be from 0 to 1.*/
+};
+
+/**
+ * @brief Contains parameters for image objects tracking.
+ *
+ * @since_tizen 3.0
+ */
+struct TrackingParams
+{
+ TrackingParams(
+ FeaturesExtractingParams framesFeaturesExtractingParams,
+ RecognitionParams recognitionParams,
+ StabilizationParams stabilizationParams,
+ double expectedOffset);
+
+ TrackingParams();
+
+ FeaturesExtractingParams mFramesFeaturesExtractingParams; /**< Parameters
+ for extracting features from frames. */
+
+ RecognitionParams mRecognitionParams; /**< Parameters for intermediate
+ recognition. */
+
+ StabilizationParams mStabilizationParams; /**< Parameters for contour
+ stabilization during tracking. */
+
+ double mExpectedOffset; /**< Relative offset value, for which expected the
+ object offset. (relative to the object size in the current
+ frame). */
+};
+
+} /* Image */
+} /* MediaVision */
+
+#endif /* __IMAGEUTIL_H__ */
diff --git a/mv_image/image/include/ImageContourStabilizator.h b/mv_image/image/include/ImageContourStabilizator.h
new file mode 100644
index 00000000..1fae7979
--- /dev/null
+++ b/mv_image/image/include/ImageContourStabilizator.h
@@ -0,0 +1,102 @@
+/**
+ * Copyright (c) 2015 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 __IMAGECONTOURSTABILIZATOR_H__
+#define __IMAGECONTOURSTABILIZATOR_H__
+
+#include "ImageConfig.h"
+
+#include <opencv/cv.h>
+
+/**
+ * @file ImageContourStabilizator.h
+ * @brief This file contains functionality for image contour stabilization
+ * during tracking.
+ */
+
+namespace MediaVision
+{
+namespace Image
+{
+
+/**
+ * @class ImageContourStabilizator
+ * @brief This class contains functionality for image contour stabilization
+ * during tracking.
+ *
+ * @since_tizen 3.0
+ */
+class ImageContourStabilizator
+{
+public:
+
+ /**
+ * @brief @ref ImageContourStabilizator default constructor.
+ *
+ * @since_tizen 3.0
+ */
+ ImageContourStabilizator();
+
+ /**
+ * @brief Stabilizes @a contour.
+ *
+ * @since_tizen 3.0
+ * @remarks Call this function alternately for each contour from sequence
+ * @param [in,out] contour @ref contour, which will be stabilized
+ * @param [in] params configuration parameters
+ * @return true if contour is stabilized, otherwise return false
+ */
+ bool stabilize(
+ std::vector<cv::Point2f>& contour,
+ const StabilizationParams& params);
+
+ /**
+ * @brief Resets stabilization process.
+ *
+ * @since_tizen 3.0
+ * @remarks Call it before starting track on the new sequence of contours.
+ */
+ void reset(void);
+
+private:
+
+ std::vector<cv::Point2f> computeStabilizedQuadrangleContour(void);
+
+private:
+
+ static const size_t MovingHistoryAmount = 3u;
+
+ std::vector<float> m_speeds;
+
+ std::vector<size_t> m_currentCornersSpeed;
+
+ std::deque<std::vector<cv::Point2f> > m_movingHistory;
+
+ std::vector<cv::Point2f> m_lastStabilizedContour;
+
+ size_t m_currentHistoryAmount;
+
+ int m_tempContourIndex;
+
+ std::vector<float> m_priorities;
+
+ bool m_isPrepared;
+};
+
+} /* Image */
+} /* MediaVision */
+
+#endif /* __IMAGECONTOURSTABILIZATOR_H__ */
diff --git a/mv_image/image/include/ImageMathUtil.h b/mv_image/image/include/ImageMathUtil.h
new file mode 100644
index 00000000..ebc95d70
--- /dev/null
+++ b/mv_image/image/include/ImageMathUtil.h
@@ -0,0 +1,78 @@
+/**
+ * Copyright (c) 2015 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 __MATHUTIL_H__
+#define __MATHUTIL_H__
+
+#include <opencv/cv.h>
+
+/**
+ * @file MathUtil.h
+ * @brief This file contains math utility for Image Module.
+ */
+
+namespace MediaVision
+{
+namespace Image
+{
+
+const size_t MinimumNumberOfFeatures = 4u; /* Minimum number of features
+ when perspective transform
+ parameters calculation
+ have sense */
+
+const size_t NumberOfQuadrangleCorners = 4u; /* Number of quadrangle corneres */
+
+/**
+ * @brief Calculates Euclidean distance between two points.
+ *
+ * @since_tizen 3.0
+ * @param [in] point1 The first point
+ * @param [in] point2 The second point
+ * @return distance between two points
+ */
+float getDistance(
+ const cv::Point2f& point1,
+ const cv::Point2f& point2);
+
+/**
+ * @brief Calculates area of triangle.
+ *
+ * @since_tizen 3.0
+ * @param [in] point1 The first corner of triangle
+ * @param [in] point2 The second corner of triangle
+ * @param [in] point3 The third corner of triangle
+ * @return area of triangle
+ */
+float getTriangleArea(
+ const cv::Point2f& point1,
+ const cv::Point2f& point2,
+ const cv::Point2f& point3);
+
+/**
+ * @brief Calculates area of quadrangle.
+ *
+ * @since_tizen 3.0
+ * @param [in] points Four corners of quadrangle
+ * @return area of quadrangle
+ */
+float getQuadrangleArea(
+ const cv::Point2f points[NumberOfQuadrangleCorners]);
+
+} /* Image */
+} /* MediaVision */
+
+#endif /* __MATHUTIL_H__ */
diff --git a/mv_image/image/include/ImageObject.h b/mv_image/image/include/ImageObject.h
new file mode 100644
index 00000000..a4945540
--- /dev/null
+++ b/mv_image/image/include/ImageObject.h
@@ -0,0 +1,220 @@
+/**
+ * Copyright (c) 2015 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 __IMAGEOBJECT_H__
+#define __IMAGEOBJECT_H__
+
+#include "ImageConfig.h"
+
+#include <opencv/cv.h>
+
+/**
+ * @file ImageObject.h
+ * @brief This file contains the @ref ImageObject class.
+ */
+
+namespace MediaVision
+{
+namespace Image
+{
+
+/**
+ * @class ImageObject
+ * @brief This class contains the image information, which will
+ * be used in recognition algorithms.
+ *
+ * @since_tizen 3.0
+ */
+class ImageObject
+{
+
+public:
+
+ /**
+ * @brief @ref ImageObject default constructor.
+ *
+ * @since_tizen 3.0
+ */
+ ImageObject();
+
+ /**
+ * @brief @ref ImageObject constructor based on image.
+ *
+ * @since_tizen 3.0
+ * @remarks Detects keypoints and extracts features from image and creates
+ * new @ref ImageObject
+ * @param [in] image The image for which instance of @ref ImageObject
+ * will be created
+ * @param [in] params Features extracting parameters
+ */
+ ImageObject(const cv::Mat& image, const FeaturesExtractingParams& params);
+
+ /**
+ * @brief @ref ImageObject copy constructor.
+ * @details Creates copy of @ref ImageObject
+ *
+ * @since_tizen 3.0
+ * @param [in] copy @ref ImageObject which will be copied
+ */
+ ImageObject(const ImageObject& copy);
+
+ /**
+ * @brief @ref ImageObject copy assignment operator.
+ * @details Fills the information based on the @a copy
+ *
+ * @since_tizen 3.0
+ * @param [in] copy @ref ImageObject which will be copied
+ *
+ */
+ ImageObject& operator=(const ImageObject& copy);
+
+ /**
+ * @brief @ref ImageObject destructor.
+ *
+ * @since_tizen 3.0
+ */
+ virtual ~ImageObject();
+
+ /**
+ * @brief Fills @ref ImageObject class based on image.
+ * @details Detects keypoints and extracts features from image and creates
+ * new @ref ImageObject
+ *
+ * @since_tizen 3.0
+ * @param [in] image The image for which instance of @ref ImageObject
+ * will be created
+ * @param [in] params Features extracting parameters
+ */
+ void fill(const cv::Mat& image, const FeaturesExtractingParams& params);
+
+ /**
+ * @brief Fills @ref ImageObject class based on image.
+ * @details Detects keypoints and extracts features from image and creates
+ * new @ref ImageObject
+ *
+ * @since_tizen 3.0
+ * @param [in] image The image for which instance of @ref
+ * ImageObject will be created
+ * @param [in] boundingBox Bounding box of the object being analyzed in
+ * the @a image
+ * @param [in] params Features extracting parameters
+ * @return @a true on success, otherwise a @a false value
+ * @retval true Successful
+ * @retval false Invalid ROI (bounding box)
+ */
+ bool fill(
+ const cv::Mat& image,
+ const cv::Rect& boundingBox,
+ const FeaturesExtractingParams& params);
+
+ /**
+ * @brief Gets a value that determines how well an @ref ImageObject can be recognized.
+ * @details Confidence can be from 0 to 1. If the recognition rate is 0 object can
+ * not be recognized
+ *
+ * @since_tizen 3.0
+ * @return A value that determines how well an @ref ImageObject can be recognized.
+ */
+ float getRecognitionRate(void) const;
+
+ /**
+ * @brief Check whether the object is filled.
+ * @details Image object is empty if it wasn't filled.
+ *
+ * @since_tizen 3.0
+ * @remarks Empty object can not be recognized or tracked. Fill the object
+ * by using corresponding constructor or function @ref fill() to
+ * make image object valid. Also you can load image object which is
+ * not empty by using @ref load().
+ * @return @c false if object is filled, otherwise return @c true
+ */
+ bool isEmpty() const;
+
+ /**
+ * @brief Sets a label for the image object.
+ *
+ * @since_tizen 3.0
+ * @param [in] label The label which will be assigned to the image object
+ */
+ void setLabel(int label);
+
+ /**
+ * @brief Gets a label of object.
+ *
+ * @since_tizen 3.0
+ * @param [out] label The label of image object
+ * @return @c true if object is labeled, otherwise return @c false
+ */
+ bool getLabel(int& label) const;
+
+ /**
+ * @brief Stores the @ref ImageObject in a file.
+ *
+ * @since_tizen 3.0
+ * @param [in] fileName File name which will be generated
+ * @return @a 0 on success, otherwise a negative error value
+ */
+ int save(const char *fileName) const;
+
+ /**
+ * @brief Loads the @ref ImageObject from the file.
+ *
+ * @since_tizen 3.0
+ * @param [in] fileName File name from which will be loaded an @ref ImageObject
+ * @return @a 0 on success, otherwise a negative error value
+ */
+ int load(const char *fileName);
+
+private:
+
+ static const int MinWidth = 5;
+ static const int MinHeight = 5;
+
+private:
+
+ void extractFeatures(
+ const cv::Mat& image,
+ const FeaturesExtractingParams& params);
+
+ void computeRecognitionRate(const cv::Mat& image);
+
+private:
+
+ bool m_isEmpty;
+
+ bool m_isLabeled;
+
+ int m_label;
+
+ std::vector<cv::Point2f> m_boundingContour;
+
+ std::vector<cv::KeyPoint> m_objectKeypoints;
+
+ cv::Mat m_objectDescriptors;
+
+ float m_recognitionRate;
+
+ friend class ImageRecognizer;
+
+ friend std::ostream& operator << (std::ostream& os, const ImageObject& obj);
+
+ friend std::istream& operator >> (std::istream& is, ImageObject& obj);
+};
+
+} /* Image */
+} /* MediaVision */
+
+#endif /* __IMAGEOBJECT_H__ */
diff --git a/mv_image/image/include/ImageRecognizer.h b/mv_image/image/include/ImageRecognizer.h
new file mode 100644
index 00000000..8494e3aa
--- /dev/null
+++ b/mv_image/image/include/ImageRecognizer.h
@@ -0,0 +1,116 @@
+/**
+ * Copyright (c) 2015 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 __IMAGERECOGNIZER_H__
+#define __IMAGERECOGNIZER_H__
+
+#include "ImageMathUtil.h"
+#include "ImageConfig.h"
+#include "ImageObject.h"
+
+#include <opencv/cv.h>
+
+/**
+ * @file ImageRecognizer.h
+ * @brief This file contains functionality for image object recognition.
+ */
+
+namespace MediaVision
+{
+namespace Image
+{
+
+/**
+ * @class ImageRecognizer
+ * @brief This class contains functionality for image object recognition.
+ *
+ * @since_tizen 3.0
+ */
+class ImageRecognizer
+{
+public:
+
+ /**
+ * @brief @ref ImageRecognizer constructor based on scene image.
+ *
+ * @since_tizen 3.0
+ * @param [in] sceneImage The scene in which image objects will be recognized
+ * @param [in] params Scene features extracting parameters
+ */
+ ImageRecognizer(const cv::Mat& sceneImage,
+ const FeaturesExtractingParams& params);
+
+ /**
+ * @brief @ref ImageRecognizer constructor based on thes scene @ref ImageObject.
+ *
+ * @since_tizen 3.0
+ * @param [in] scene The scene for which the objects will be recognized by
+ * calling method recognize()
+ */
+ ImageRecognizer(const ImageObject& scene);
+
+ /**
+ * @brief @ref ImageRecognizer destructor.
+ *
+ * @since_tizen 3.0
+ */
+ virtual ~ImageRecognizer();
+
+ /**
+ * @brief Recognizes the @a target on the scene.
+ *
+ * @since_tizen 3.0
+ * @param [in] target @ref ImageObject, which will be recognized
+ * @param [in] params Recognition parameters
+ * @param [out] contour The result contour of @a target object on the scene
+ * @return true if object is found on the scene, otherwise return false
+ */
+ bool recognize(
+ const ImageObject& target,
+ const RecognitionParams& params,
+ std::vector<cv::Point2f>& contour) const;
+
+private:
+
+ ImageRecognizer();
+
+ bool findHomophraphyMatrix(
+ const ImageObject& target,
+ const RecognitionParams& params,
+ cv::Mat& homophraphyMatrix) const;
+
+ size_t matchesSelection(
+ std::vector<cv::DMatch>& examples,
+ unsigned int filterAmount, unsigned int allowableError) const;
+
+ float computeLinearSupportElement(
+ const std::vector<cv::DMatch>& examples,
+ int requiredNumber, int leftLimit, int rightLimit) const;
+
+ static bool isPossibleQuadrangleCorners(
+ const cv::Point2f corners[NumberOfQuadrangleCorners]);
+
+private:
+
+ ImageObject m_scene;
+
+ cv::BFMatcher m_matcher;
+};
+
+} /* Image */
+} /* MediaVision */
+
+#endif /* __IMAGERECOGNIZER_H__ */
diff --git a/mv_image/image/include/ImageTracker.h b/mv_image/image/include/ImageTracker.h
new file mode 100644
index 00000000..2bfd5b1b
--- /dev/null
+++ b/mv_image/image/include/ImageTracker.h
@@ -0,0 +1,103 @@
+/**
+ * Copyright (c) 2015 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 __IMAGETRACKER_H__
+#define __IMAGETRACKER_H__
+
+#include "ImageConfig.h"
+
+#include <opencv/cv.h>
+
+/**
+ * @file ImageTracker.h
+ * @brief This file contains functionality for image object tracking.
+ */
+
+namespace MediaVision
+{
+namespace Image
+{
+
+class ImageRecognizer;
+class ImageTrackingModel;
+
+/**
+ * @class ImageTracker
+ * @brief This class contains functionality for image object tracking.
+ *
+ * @since_tizen 3.0
+ */
+class ImageTracker
+{
+private:
+
+ struct RecognitionInfo
+ {
+ cv::Mat mFrame;
+
+ RecognitionParams mRecognitionParams;
+
+ FeaturesExtractingParams mSceneFeaturesExtractingParams;
+
+ ImageTrackingModel *mpTarget;
+ };
+
+ static void *recognitionThreadFunc(void *recognitionInfo);
+
+public:
+
+ /**
+ * @brief @ref ImageTracker constructor based on tracking algorithm
+ * parameters.
+ *
+ * @since_tizen 3.0
+ * @param [in] trackingParams Parameters for image objects tracking
+ */
+ ImageTracker(const TrackingParams& trackingParams);
+
+ /**
+ * @brief Tracks the @a target for the video stream consisting of frames.
+ *
+ * @since_tizen 3.0
+ * @remarks Call this function alternately for each frame
+ * @param [in] frame Current frame of the video stream
+ * @param [in,out] target @ref ImageTrackingModel, which will be tracked
+ */
+ void track(const cv::Mat& frame, ImageTrackingModel& target);
+
+private:
+
+ void trackDetectedObject(
+ const cv::Mat& frame,
+ ImageTrackingModel& target);
+
+ void trackUndetectedObject(
+ const cv::Mat& frame,
+ ImageTrackingModel& target);
+
+ cv::Rect computeExpectedArea(
+ const ImageTrackingModel& target,
+ const cv::Size& frameSize);
+
+private:
+
+ TrackingParams m_trackingParams;
+};
+
+} /* Image */
+} /* MediaVision */
+
+#endif /* __IMAGETRACKER_H__ */
diff --git a/mv_image/image/include/ImageTrackingModel.h b/mv_image/image/include/ImageTrackingModel.h
new file mode 100644
index 00000000..2f55c2d1
--- /dev/null
+++ b/mv_image/image/include/ImageTrackingModel.h
@@ -0,0 +1,219 @@
+/**
+ * Copyright (c) 2015 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 __IMAGETRACKINGMODEL_H__
+#define __IMAGETRACKINGMODEL_H__
+
+#include "ImageObject.h"
+
+#include "ImageContourStabilizator.h"
+
+#include <opencv/cv.h>
+
+#include <pthread.h>
+
+#include <vector>
+#include <list>
+
+/**
+ * @file ImageTrackingModel.h
+ * @brief This file contains the @ref ImageTrackingModel class.
+ */
+
+namespace MediaVision
+{
+namespace Image
+{
+
+class ImageContourStabilizator;
+
+/**
+ * @class ImageTrackingModel
+ * @brief This class contains the tracking functionality for image objects.
+ *
+ * @since_tizen 3.0
+ */
+class ImageTrackingModel
+{
+private:
+ /**
+ * @brief @ref ImageTrackingModel state enumeration.
+ *
+ * @since_tizen 3.0
+ */
+ enum State
+ {
+ Invalid, /**< Invalid tracking model can not be tracked. Set not
+ empty image object as target by using function
+ @ref setTarget() to make tracking model valid, also
+ you can load valid tracking model by using @ref load() */
+ Undetected, /**< The object was not recognized on the last frame. Ready
+ for further recognition */
+ Appeared, /**< The object was recognized on one of the last frames
+ after its absence */
+ Tracked, /**< The object was recognized on the last frame. Its
+ location can be obtained by calling method getLocation() */
+ InProcess /**< The object is in the recognition process */
+ };
+
+public:
+
+ /**
+ * @brief @ref ImageTrackingModel default constructor
+ *
+ * @since_tizen 3.0
+ */
+ ImageTrackingModel();
+
+ /**
+ * @brief @ref ImageTrackingModel constructor based on tracking algorithm
+ * parameters.
+ *
+ * @since_tizen 3.0
+ * @param[in] recognitionObject @ref ImageObject which will be tracked
+ */
+ ImageTrackingModel(const ImageObject& recognitionObject);
+
+ /**
+ * @brief @ref ImageTrackingModel copy constructor.
+ * @details Creates copy of @ref ImageTrackingModel
+ *
+ * @since_tizen 3.0
+ * @param [in] copy @ref ImageTrackingModel which will be copied
+ */
+ ImageTrackingModel(const ImageTrackingModel& copy);
+
+ /**
+ * @brief @ref ImageTrackingModel destructor.
+ *
+ * @since_tizen 3.0
+ */
+ ~ImageTrackingModel();
+
+ /**
+ * @brief Sets @ref ImageObject as target which will be tracked.
+ *
+ * @since_tizen 3.0
+ * @param [in] target @ref ImageObject which will be tracked
+ */
+ void setTarget(const ImageObject& target);
+
+ /**
+ * @brief Checks whether the tracking model is valid for tracking.
+ * @details Image tracking model is valid if its target is set and not empty.
+ *
+ * @since_tizen 3.0
+ * @remarks Invalid tracking model can not be tracked. Set not empty target
+ * by using corresponding constructor or function @ref setTarget()
+ * to make tracking model valid. Also you can load valid tracking
+ * model by using @ref load().
+ * @return @c true if tracking model is valid, otherwise return @c false
+ */
+ bool isValid() const;
+
+ /**
+ * @brief Refreshes tracking model.
+ *
+ * @since_tizen 3.0
+ * @remarks Call it before starting track on the new video stream.
+ */
+ void refresh(void);
+
+ /**
+ * @brief @ref ImageTrackingModel copy assignment operator.
+ * @details Fills the information based on the @a copy
+ *
+ * @since_tizen 3.0
+ * @param [in] copy @ref ImageTrackingModel which will be copied
+ */
+ ImageTrackingModel& operator=(const ImageTrackingModel& copy);
+
+ /**
+ * @brief Stores the @ref ImageTrackingModel in a file.
+ *
+ * @since_tizen 3.0
+ * @param [in] filepath File name which will be generated
+ * @return @a 0 on success, otherwise a negative error value
+ */
+ int save(const char *filepath) const;
+
+ /**
+ * @brief Loads the @ref ImageTrackingModel from the file.
+ *
+ * @since_tizen 3.0
+ * @param [in] filepath File name from which will be loaded a model
+ * @return @a 0 on success, otherwise a negative error value
+ */
+ int load(const char *filepath);
+
+ /**
+ * @brief Checks state of the @ref ImageTrackingModel.
+ *
+ * @since_tizen 3.0
+ * @return @a true if object was detected on the last processed frame,
+ * otherwise a @a false value
+ */
+ bool isDetected() const;
+
+ /**
+ * @brief Gets last location of the @ref ImageTrackingModel.
+ *
+ * @since_tizen 3.0
+ * @return Last detected location
+ */
+ std::vector<cv::Point2f> getLastlocation() const;
+
+private:
+
+ ImageObject m_recognitionObject;
+
+ ImageContourStabilizator m_stabilizator;
+
+ std::vector<cv::Point2f> m_lastLocation;
+
+ State m_state;
+
+ pthread_t m_recognitionThread;
+
+ mutable pthread_mutex_t m_globalGuard;
+
+ mutable pthread_spinlock_t m_lastLocationGuard;
+
+ mutable pthread_spinlock_t m_stateGuard;
+
+ friend std::ostream& operator << (
+ std::ostream& os,
+ const ImageTrackingModel::State& state);
+
+ friend std::istream& operator >> (
+ std::istream& is,
+ ImageTrackingModel::State& state);
+
+ friend std::ostream& operator << (
+ std::ostream& os,
+ const ImageTrackingModel& obj);
+
+ friend std::istream& operator >> (
+ std::istream& is,
+ ImageTrackingModel& obj);
+
+ friend class ImageTracker;
+};
+
+} /* Image */
+} /* MediaVision */
+
+#endif /* __IMAGETRACKINGMODEL_H__ */
diff --git a/mv_image/image/include/mv_image_open.h b/mv_image/image/include/mv_image_open.h
new file mode 100644
index 00000000..f6128fd5
--- /dev/null
+++ b/mv_image/image/include/mv_image_open.h
@@ -0,0 +1,561 @@
+/**
+ * Copyright (c) 2015 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 __TIZEN_MEDIAVISION_IMAGE_OPEN_H__
+#define __TIZEN_MEDIAVISION_IMAGE_OPEN_H__
+
+#include "mv_image.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @file mv_image_open.h
+ * @brief This file contains the Media Vision Image API for the open module.
+ * Working with images (like planar objects): recognition and tracking.
+ */
+
+/****************************/
+/* Image object recognition */
+/****************************/
+
+/**
+ * @brief Recognizes the given image objects on the source image.
+ * @details Use this function to launch image recognition algorithm configured
+ * by @a engine_conf configuration.
+ *
+ * @since_tizen 3.0
+ * @param [in] source The handle to the source image on which image
+ * objects will be recognized
+ * @param [in] image_objects The set of handles to the image objects which
+ * will be processed as targets of recognition
+ * @param [in] number_of_objects The number of image objects
+ * @param [in] engine_cfg The handle to the configuration of engine
+ * which will be used for recognition. If NULL,
+ * then default settings will be used.
+ * @param [in] recognized_cb The callback which will be called in order to
+ * process recognition result
+ * @param [in] user_data The user data to be passed to the
+ * @a recognized_cb
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT Source colorspace
+ * isn't supported
+ *
+ * @pre Create a set of image objects using @ref mv_image_object_create_open()
+ * for each of them and construct (fill / load / clone) them on images that
+ * will be recognized
+ * @pre Create a source handle by calling @ref mv_create_source() and fill
+ * by the image for which recognition will be performed
+ * @post @a mv_image_recognized_cb will be called to process recognition result
+ * @post Release source image by using @ref mv_destroy_source()
+ * @post Release image objects by using @ref mv_image_object_destroy_open() for
+ * each handle from @a image_objects set
+ *
+ * @see mv_image_recognized_cb
+ * @see mv_source_h
+ * @see mv_create_source()
+ * @see mv_destroy_source()
+ * @see mv_image_object_h
+ * @see mv_image_object_create_open()
+ * @see mv_image_object_destroy_open()
+ * @see mv_engine_config_h
+ */
+int mv_image_recognize_open(
+ mv_source_h source,
+ const mv_image_object_h *image_objects,
+ int number_of_objects,
+ mv_engine_config_h engine_cfg,
+ mv_image_recognized_cb recognized_cb,
+ void *user_data);
+
+/*************************/
+/* Image object tracking */
+/*************************/
+
+/**
+ * @brief Tracks the given image tracking model on the current frame
+ * @details Image tracking on a sequence of frames assumes calling this
+ * function for each frame in the correct order.
+ * @a tracked_cb will be called for result processing.
+ *
+ * @since_tizen 3.0
+ * @remarks Tracking algorithm is usually using for recognition of image object
+ * on the sequence of images that are organized by time. For example,
+ * it may be the sequence of frames from a video stream.
+ * @remarks If object is lost during the tracking, system tries to find it
+ * further for the following frames. Therefore, tracking will be
+ * recovered when object appears again.
+ * @remarks Previous calls of @ref mv_image_track_open() for this
+ * @a image_tracking_model will affect on current call
+ * @param [in] source The handle to the current image of
+ * sequence where image tracking model
+ * will be tracked
+ * @param [in,out] image_tracking_model The handle to the image tracking model
+ * which processed as target of tracking
+ * @param [in] engine_cfg The handle to the configuration of
+ * engine which will be used for tracking.
+ * If NULL, then default settings will be
+ * used.
+ * @param [in] tracked_cb The callback which will receive
+ * tracking results
+ * @param [in] user_data The user data to be passed to the
+ * @a tracked_cb
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT Source colorspace
+ * isn't supported
+ *
+ * @pre Create image tracking model by calling
+ * @ref mv_image_tracking_model_create_open() and set target by calling
+ * @ref mv_image_tracking_model_set_target_open()
+ * @pre Create a source images by calling @ref mv_create_source() for each of
+ * them and construct them based on sequence of images for which will be
+ * held image tracking
+ * @post @a tracked_cb will be called to process tracking result
+ * @post Release image tracking model by using
+ * @ref mv_image_tracking_model_destroy_open()
+ *
+ * @see mv_image_tracked_cb
+ * @see mv_source_h
+ * @see image_tracking_model_h
+ * @see mv_image_tracking_model_create_open()
+ * @see mv_image_tracking_model_set_target_open()
+ * @see mv_image_tracking_model_destroy_open()
+ */
+int mv_image_track_open(
+ mv_source_h source,
+ mv_image_tracking_model_h image_tracking_model,
+ mv_engine_config_h engine_cfg,
+ mv_image_tracked_cb tracked_cb,
+ void *user_data);
+
+/**************************/
+/* Image object behaviour */
+/**************************/
+
+/**
+ * @brief Creates an image object.
+ *
+ * @since_tizen 3.0
+ * @param [out] image_object A new handle to the image object
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_OUT_OF_MEMORY Out of memory
+ *
+ * @pre Release image object by using mv_image_object_destroy_open()
+ *
+ * @see mv_image_object_destroy_open()
+ */
+int mv_image_object_create_open(
+ mv_image_object_h *image_object);
+
+/**
+ * @brief Destroys the image object.
+ *
+ * @since_tizen 3.0
+ * @param [in] image_object The handle to the image object to be destroyed
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @see mv_image_object_create_open()
+ */
+int mv_image_object_destroy_open(
+ mv_image_object_h image_object);
+
+/**
+ * @brief Fills the image object.
+ * @details Extracts data from @a source image which will be needed for
+ * recognition of depicted object in @a location.
+ *
+ * @since_tizen 3.0
+ * @remarks After filling the image object it can be evaluated by
+ * @ref mv_image_object_get_recognition_rate_open(). If recognition
+ * rate is too low, try to use another image of object or change
+ * configuration parameters (see @ref mv_engine_config_h) and construct
+ * the image object again.
+ * @param [in,out] image_object The handle to the image object which will be
+ * filled and can be recognized in future
+ * @param [in] engine_cfg The handle to the configuration of engine
+ * which will be used for extract recognition
+ * data from @a source. If NULL, then default
+ * settings will be used.
+ * @param [in] source The source image where image object is depicted
+ * @param [in] location The pointer to location of the image object
+ * on the source image, or NULL if the object is
+ * shown in full
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT Source colorspace
+ * isn't supported
+ *
+ * @pre Create image object by using @ref mv_image_object_create_open()
+ * @post Release image object by using @ref mv_image_object_destroy_open()
+ *
+ * @see mv_image_object_h
+ * @see mv_image_object_create_open()
+ * @see mv_image_object_get_recognition_rate_open()
+ * @see mv_image_recognize_open()
+ * @see mv_image_object_destroy_open()
+ * @see mv_engine_config_h
+ */
+int mv_image_object_fill_open(
+ mv_image_object_h image_object,
+ mv_engine_config_h engine_cfg,
+ mv_source_h source,
+ mv_rectangle_s *location);
+
+/**
+ * @brief Gets a value that determines how well an image object can be recognized.
+ * @details Recognition rate determines how well an image object can be
+ * recognized. This value can be from 0 to 1. If the recognition rate
+ * is 0 object can not be recognized and the bigger it is the more
+ * likely to recognize the object.
+ *
+ * @since_tizen 3.0
+ * @remarks If recognition rate is too low, try to use another image of object
+ * or change some configuration parameters (see @ref mv_engine_config_h)
+ * and fill the image object again
+ * (see @ref mv_image_object_fill_open()).
+ * @param [in] image_object The handle to the image object which will be
+ * evaluated by this function
+ * @param [out] recognition_rate A value that determines how well an image
+ * object can be recognized, if 0 then object
+ * can not be recognized
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @pre Create image object by using @ref mv_image_object_create_open()
+ * @post Release image object by using @ref mv_image_object_destroy_open()
+ *
+ * @see mv_image_object_h
+ * @see mv_image_object_create_open()
+ * @see mv_image_object_fill_open()
+ * @see mv_image_object_destroy_open()
+ * @see mv_engine_config_h
+ */
+int mv_image_object_get_recognition_rate_open(
+ mv_image_object_h image_object,
+ double *recognition_rate);
+
+/**
+ * @brief Sets a label for the image object.
+ *
+ * @since_tizen 3.0
+ * @param [in] image_object The handle to the image object for which the label
+ * will be assigned
+ * @param [in] label The label which will be assigned to the image
+ * object
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @pre Create image object by using @ref mv_image_object_create_open()
+ * @post Label could be received by using
+ * @ref mv_image_object_get_label_open()
+ * @post Release image object by using @ref mv_image_object_destroy_open()
+ *
+ * @see mv_image_object_get_label_open()
+ * @see mv_image_object_h
+ * @see mv_image_object_create_open()
+ * @see mv_image_object_destroy_open()
+ */
+int mv_image_object_set_label_open(
+ mv_image_object_h image_object,
+ int label);
+
+/**
+ * @brief Gets a label of image object.
+ *
+ * @since_tizen 3.0
+ * @remarks If @a image_object have not a label, this function return
+ * MEDIA_VISION_ERROR_NO_DATA value.
+ * @param [in] image_object The handle to the image object from which a
+ * label will be received
+ * @param [out] label The label of image object
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NO_DATA Image object hasn't label
+ *
+ * @pre Create image object by using @ref mv_image_object_create_open()
+ * @pre Set label for the image object by using
+ * @ref mv_image_object_set_label_open()
+ * @post Release image object by using @ref mv_image_object_destroy_open()
+ *
+ * @see mv_image_object_set_label_open()
+ * @see mv_image_object_h
+ * @see mv_image_object_create_open()
+ * @see mv_image_object_destroy_open()
+ */
+int mv_image_object_get_label_open(
+ mv_image_object_h image_object,
+ int *label);
+
+/**
+ * @brief Clones the image object.
+ *
+ * @since_tizen 3.0
+ * @remarks @a dst must be released using mv_image_object_destroy_open().
+ * @param [in] src The handle to the source image object
+ * @param [out] dst The handle to the destination image object
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_OUT_OF_MEMORY Out of memory
+ *
+ * @pre Create image object handles by calling mv_image_object_create_open()
+ *
+ * @see mv_image_object_create_open()
+ * @see mv_image_object_destroy_open()
+ */
+int mv_image_object_clone_open(
+ mv_image_object_h src,
+ mv_image_object_h *dst);
+
+/**
+ * @brief Saves the image object.
+ *
+ * @since_tizen 3.0
+ * @remarks @a image_object is saved to the application's data directory.
+ * @param [in] file_name Name of the file to save the image object
+ * @param [in] image_object The handle to the image object which will be saved
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_PATH Invalid path
+ * @retval #MEDIA_VISION_ERROR_PERMISSION_DENIED Not permitted
+ *
+ * @see mv_image_object_create_open()
+ * @see mv_image_object_load_open()
+ * @see mv_image_object_destroy_open()
+ */
+int mv_image_object_save_open(
+ const char *file_name, mv_image_object_h image_object);
+
+/**
+ * @brief Loads an image object from the file.
+ *
+ * @since_tizen 3.0
+ * @remarks @a image_object is loaded from the application's data directory.
+ * @a image_object must be destroyed using
+ * @ref mv_image_object_destroy().
+ * @param [in] file_name Name of file to load the image object
+ * @param [out] image_object The handle to the image object which will be
+ * filled
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_PATH Invalid path
+ * @retval #MEDIA_VISION_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #MEDIA_VISION_ERROR_PERMISSION_DENIED Not permitted
+ *
+ * @pre Image object can be preliminary saved with mv_image_object_save()
+ * function
+ *
+ * @see mv_image_object_save_open()
+ * @see mv_image_object_destroy_open()
+ */
+int mv_image_object_load_open(
+ const char *file_name, mv_image_object_h *image_object);
+
+/**********************************/
+/* Image tracking model behaviour */
+/**********************************/
+
+/**
+ * @brief Creates an image tracking model.
+ *
+ * @since_tizen 3.0
+ * @param [out] image_tracking_model A new handle to the image tracking model
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_OUT_OF_MEMORY Out of memory
+ *
+ * @pre Release image tracking model by using mv_image_tracking_model_destroy_open()
+ *
+ * @see mv_image_tracking_model_destroy_open()
+ */
+int mv_image_tracking_model_create_open(
+ mv_image_tracking_model_h *image_tracking_model);
+
+/**
+ * @brief Sets target of image tracking model.
+ * @details Sets image object which will be tracked by using tracking
+ * functionality with @a image_tracking_model.
+ *
+ * @since_tizen 3.0
+ * @param [in] image_object Image object which will be set
+ * as target for tracking
+ * @param [in] image_tracking_model Handle to the image tracking model
+ * for which will be set a new target
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @pre Create image tracking model by calling
+ * @ref mv_image_tracking_model_create_open()
+ * @pre Create an image object using @ref mv_image_object_create_open() and
+ * construct (fill / load / clone) it on image that will be tracking
+ * @post Release image object by using @ref mv_image_object_destroy_open()
+ * @post Release image tracking model by using
+ * @ref mv_image_tracking_model_destroy_open()
+ *
+ * @see mv_image_object_h
+ * @see mv_image_tracking_model_h
+ * @see mv_image_object_create_open()
+ * @see mv_image_object_destroy_open()
+ * @see mv_image_tracking_model_create_open()
+ * @see mv_image_track_open()
+ * @see mv_image_tracking_model_destroy_open()
+ */
+int mv_image_tracking_model_set_target_open(
+ mv_image_object_h image_object,
+ mv_image_tracking_model_h image_tracking_model);
+
+/**
+ * @brief Destroys the image tracking model.
+ *
+ * @since_tizen 3.0
+ * @param [in] image_tracking_model The handle to the image tracking model
+ * to be destroyed
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @pre Create image tracking model by using mv_image_tracking_model_create()
+ *
+ * @see mv_image_tracking_model_create_open()
+ */
+int mv_image_tracking_model_destroy_open(
+ mv_image_tracking_model_h image_tracking_model);
+
+/**
+ * @brief Refreshes the state of image tracking model.
+ * @details Clears moving history and change state to undetected. This function
+ * is usually called each time before tracking is started for the new
+ * sequence of sources which is not the direct continuation of the
+ * sequence for which tracking has been performed before. Tracking
+ * algorithm will try to find image by itself.
+ *
+ * @since_tizen 3.0
+ * @param [in] image_tracking_model The handle to the image tracking model
+ * which will be refreshed
+ * @param [in] engine_cfg The handle to the configuration of
+ * engine which will be used. If NULL,
+ * then default settings will be used.
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @pre Create image tracking model by calling
+ * @ref mv_image_tracking_model_create_open()
+ * @post Release image tracking model by using
+ * @ref mv_image_tracking_model_destroy_open()
+ *
+ * @see mv_image_tracking_model_h
+ * @see mv_image_tracking_model_create_open()
+ * @see mv_image_track_open()
+ * @see mv_image_tracking_model_destroy_open()
+ */
+int mv_image_tracking_model_refresh_open(
+ mv_image_tracking_model_h image_tracking_model,
+ mv_engine_config_h engine_cfg);
+
+/**
+ * @brief Clones the image tracking model.
+ *
+ * @since_tizen 3.0
+ * @remarks @a dst must be released using mv_image_tracking_model_destroy_open().
+ * @param [in] src The handle to the source image tracking model
+ * @param [out] dst The handle to the destination image tracking model
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_OUT_OF_MEMORY Out of memory
+ *
+ * @see mv_image_tracking_model_create_open()
+ * @see mv_image_tracking_model_destroy_open()
+ */
+int mv_image_tracking_model_clone_open(
+ mv_image_tracking_model_h src,
+ mv_image_tracking_model_h *dst);
+
+/**
+ * @brief Saves the image tracking model.
+ *
+ * @since_tizen 3.0
+ * @remarks @a image_tracking_model is saved to the application's data directory.
+ * @param [in] file_name Name of file to save the model
+ * @param [in] image_tracking_model The handle to the image tracking model
+ * to be saved
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_PATH Invalid path
+ * @retval #MEDIA_VISION_ERROR_PERMISSION_DENIED Not permitted
+ *
+ * @pre Create image tracking model handle by calling
+ * mv_image_tracking_model_create()
+ * @post Saved model can be loaded later by calling
+ * mv_image_tracking_model_load() function
+
+ * @see mv_image_tracking_model_create_open()
+ * @see mv_image_tracking_model_load_open()
+ * @see mv_image_tracking_model_destroy_open()
+ */
+int mv_image_tracking_model_save_open(
+ const char *file_name, mv_image_tracking_model_h image_tracking_model);
+
+/**
+ * @brief Loads an image tracking model from the file.
+ *
+ * @since_tizen 3.0
+ * @remarks @a image_tracking_model is loaded from the application's data directory.
+ * @a image_tracking_model must be destroyed using
+ * @ref mv_image_tracking_model_destroy.
+ * @param [in] file_name Name of file to load model
+ * @param [out] image_tracking_model The handle to the image tracking
+ * model to be filled
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_PATH Invalid path
+ * @retval #MEDIA_VISION_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #MEDIA_VISION_ERROR_PERMISSION_DENIED Not permitted
+ *
+ * @pre Image tracking model handle can be preliminary saved with
+ * mv_image_tracking_model_save() function
+ *
+ * @see mv_image_tracking_model_save_open()
+ * @see mv_image_tracking_model_destroy_open()
+ */
+int mv_image_tracking_model_load_open(
+ const char *file_name, mv_image_tracking_model_h *image_tracking_model);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __TIZEN_MEDIAVISION_IMAGE_OPEN_H__ */
diff --git a/mv_image/image/src/ImageConfig.cpp b/mv_image/image/src/ImageConfig.cpp
new file mode 100644
index 00000000..47fdaef4
--- /dev/null
+++ b/mv_image/image/src/ImageConfig.cpp
@@ -0,0 +1,104 @@
+/**
+ * Copyright (c) 2015 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 "ImageConfig.h"
+
+namespace MediaVision
+{
+namespace Image
+{
+
+FeaturesExtractingParams::FeaturesExtractingParams(
+ double scaleFactor,
+ int maximumFeaturesNumber) :
+ mScaleFactor(scaleFactor),
+ mMaximumFeaturesNumber(maximumFeaturesNumber)
+{
+ ; /* NULL */
+}
+
+FeaturesExtractingParams::FeaturesExtractingParams() :
+ mScaleFactor(1.2),
+ mMaximumFeaturesNumber(800)
+{
+ ; /* NULL */
+}
+
+RecognitionParams::RecognitionParams(
+ int minMatchesNumber,
+ double requiredMatchesPart,
+ double allowableMatchesPartError) :
+ mMinMatchesNumber(minMatchesNumber),
+ mRequiredMatchesPart(requiredMatchesPart),
+ mAllowableMatchesPartError(allowableMatchesPartError)
+{
+ ; /* NULL */
+}
+
+RecognitionParams::RecognitionParams() :
+ mMinMatchesNumber(0),
+ mRequiredMatchesPart(1.0),
+ mAllowableMatchesPartError(0.0)
+{
+ ; /* NULL */
+}
+
+StabilizationParams::StabilizationParams(
+ int historyAmount,
+ double allowableShift,
+ double stabilizationSpeed,
+ double stabilizationAcceleration) :
+ mHistoryAmount(historyAmount),
+ mAllowableShift(allowableShift),
+ mStabilizationSpeed(stabilizationSpeed),
+ mStabilizationAcceleration(stabilizationAcceleration)
+{
+ ; /* NULL */
+}
+
+StabilizationParams::StabilizationParams() :
+ mHistoryAmount(1),
+ mAllowableShift(0.0),
+ mStabilizationSpeed(0.0),
+ mStabilizationAcceleration(1.0)
+{
+ ; /* NULL */
+}
+
+TrackingParams::TrackingParams(
+ FeaturesExtractingParams framesFeaturesExtractingParams,
+ RecognitionParams recognitionParams,
+ StabilizationParams stabilizationParams,
+ double expectedOffset) :
+ mFramesFeaturesExtractingParams(framesFeaturesExtractingParams),
+ mRecognitionParams(recognitionParams),
+ mStabilizationParams(stabilizationParams),
+ mExpectedOffset(expectedOffset)
+{
+ ; /* NULL */
+}
+
+TrackingParams::TrackingParams() :
+ mFramesFeaturesExtractingParams(),
+ mRecognitionParams(),
+ mStabilizationParams(),
+ mExpectedOffset(0.0)
+{
+ ; /* NULL */
+}
+
+} /* Image */
+} /* MediaVision */
diff --git a/mv_image/image/src/ImageContourStabilizator.cpp b/mv_image/image/src/ImageContourStabilizator.cpp
new file mode 100644
index 00000000..1c486593
--- /dev/null
+++ b/mv_image/image/src/ImageContourStabilizator.cpp
@@ -0,0 +1,300 @@
+/**
+ * Copyright (c) 2015 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 "ImageContourStabilizator.h"
+#include "ImageMathUtil.h"
+
+#include "mv_private.h"
+
+namespace MediaVision
+{
+namespace Image
+{
+
+ImageContourStabilizator::ImageContourStabilizator() :
+ m_movingHistory(MovingHistoryAmount),
+ m_priorities(MovingHistoryAmount)
+{
+ reset();
+
+ // increasing the stabilization rate
+ m_speeds.push_back(0.3f);
+ m_speeds.push_back(0.4f);
+ m_speeds.push_back(0.5f);
+ m_speeds.push_back(0.6f);
+ m_speeds.push_back(0.8f);
+ m_speeds.push_back(1.f);
+
+ // calculation of priorities for positions in the moving history
+ for (size_t i = 0u; i < MovingHistoryAmount; ++i)
+ {
+ // linear dependence on the elapsed time
+ m_priorities[i] = (i + 1) / ((MovingHistoryAmount + 1) * MovingHistoryAmount / 2.0f);
+ }
+}
+
+void ImageContourStabilizator::reset(void)
+{
+ m_isPrepared = false;
+ m_tempContourIndex = -1;
+ m_currentHistoryAmount = 0;
+
+ LOGI("Outlier is detected.");
+}
+
+bool ImageContourStabilizator::stabilize(
+ std::vector<cv::Point2f>& contour,
+ const StabilizationParams& /*params*/)
+{
+ // current implementation stabilizes quadrangles only
+ if (contour.size() != NumberOfQuadrangleCorners)
+ {
+ LOGW("Not stabilized. Empty contour.");
+
+ return false;
+ }
+
+ m_currentCornersSpeed.resize(contour.size(), 0);
+
+ if (contour[0].x == contour[1].x && contour[0].y == contour[1].y)
+ {
+ LOGW("Not stabilized. Invalid contour.");
+
+ return false;
+ }
+
+ if (m_lastStabilizedContour.empty())
+ {
+ m_lastStabilizedContour = contour;
+ }
+
+ std::vector<cv::Point2f> stabilizedState;
+
+ // history amount < 2 it's no sense
+ if (MovingHistoryAmount >= 2)
+ {
+ // first sample
+ if (m_tempContourIndex == -1)
+ {
+ m_movingHistory[1] = contour;
+ m_tempContourIndex = 1;
+ m_currentHistoryAmount = 1;
+
+ LOGI("Not stabilized. Too small moving history. (the first one)");
+
+ return false;
+ }
+
+ // too short moving history
+ if (m_currentHistoryAmount < MovingHistoryAmount - 1)
+ {
+ ++m_currentHistoryAmount;
+ ++m_tempContourIndex;
+ m_movingHistory[m_tempContourIndex] = contour;
+
+ LOGI("Not stabilized. Too small moving history.");
+
+ return false;
+ }
+
+ // saving into moving history
+ m_movingHistory.pop_front();
+ m_movingHistory.push_back(contour);
+
+ if (!m_isPrepared)
+ {
+ m_lastStabilizedContour = m_movingHistory[MovingHistoryAmount - 2];
+
+ LOGI("Not stabilized. Too small moving history. (the last one)");
+
+ m_isPrepared = true;
+ }
+
+ // stabilization
+ stabilizedState = computeStabilizedQuadrangleContour();
+
+ if (stabilizedState.empty())
+ {
+ stabilizedState = m_lastStabilizedContour;
+ }
+ }
+ else
+ {
+ stabilizedState = m_lastStabilizedContour;
+ }
+
+ const float tolerantShift = getQuadrangleArea(contour.data()) * 0.00006f + 1.3f;
+
+ const size_t contourSize = stabilizedState.size();
+ for (size_t i = 0u; i < contourSize; ++i)
+ {
+ if (fabs(getDistance(stabilizedState[i], contour[i])) > tolerantShift)
+ {
+ const float dirX = m_lastStabilizedContour[i].x - contour[i].x;
+ const float dirY = m_lastStabilizedContour[i].y - contour[i].y;
+
+ const float speedX = dirX * m_speeds[m_currentCornersSpeed[i]];
+ const float speedY = dirY * m_speeds[m_currentCornersSpeed[i]];
+
+ // final moving
+ m_lastStabilizedContour[i].x -= speedX;
+ m_lastStabilizedContour[i].y -= speedY;
+
+ if (m_currentCornersSpeed[i] < m_speeds.size() - 1)
+ {
+ ++m_currentCornersSpeed[i];
+ }
+ }
+ else
+ {
+ m_currentCornersSpeed[i] = 0;
+ }
+ }
+
+ // m_lastStabilizedContour = stabilizedState;
+ contour = m_lastStabilizedContour;
+
+ LOGI("Contour successfully stabilized.");
+
+ return true;
+}
+
+std::vector<cv::Point2f> ImageContourStabilizator::computeStabilizedQuadrangleContour(void)
+{
+ // final contour
+ std::vector<cv::Point2f> stabilizedState(
+ NumberOfQuadrangleCorners, cv::Point2f(0.f, 0.f));
+
+ // calculation the direction of contour corners to a new location
+ std::vector<cv::Point2f> directions(
+ NumberOfQuadrangleCorners, cv::Point2f(0.f, 0.f));
+
+ // computing expected directions and outliers searching
+ bool expressiveTime = false;
+ float summPriorityWithoutToLastPos[NumberOfQuadrangleCorners];
+ float priorityToLastPos[NumberOfQuadrangleCorners];
+ std::vector<cv::Point2f> directionsToLastPos(NumberOfQuadrangleCorners);
+ for (size_t j = 0u; j < NumberOfQuadrangleCorners; ++j)
+ {
+ // calculation the moving directions and computing average direction
+ std::vector<cv::Point2f> trackDirections(MovingHistoryAmount - 1);
+ cv::Point2f averageDirections(0.f, 0.f);
+
+ for (size_t i = 0u; i < MovingHistoryAmount - 1; ++i)
+ {
+ averageDirections.x += (trackDirections[i].x =
+ m_movingHistory[i+1][j].x - m_movingHistory[i][j].x) /
+ (MovingHistoryAmount - 1);
+
+ averageDirections.y += (trackDirections[i].y =
+ m_movingHistory[i+1][j].y - m_movingHistory[i][j].y) /
+ (MovingHistoryAmount - 1);
+ }
+
+ // calculation a deviations and select outlier
+ std::vector<float> directionDistances(MovingHistoryAmount - 1);
+ float maxDistance = 0.f, prevMaxDistance = 0.f;
+ int idxWithMaxDistance = 0;
+ int numExpressiveDirection = -1;
+ for (size_t i = 0u; i < MovingHistoryAmount - 1; ++i)
+ {
+ directionDistances[i] = getDistance(
+ trackDirections[i],
+ averageDirections);
+
+ if (directionDistances[i] > prevMaxDistance)
+ {
+ if (directionDistances[i] > maxDistance)
+ {
+ prevMaxDistance = maxDistance;
+ maxDistance = directionDistances[i];
+ idxWithMaxDistance = i;
+ }
+ else
+ {
+ prevMaxDistance = directionDistances[i];
+ }
+ }
+ }
+
+ // check outlier
+ if (0.6f * maxDistance > prevMaxDistance)
+ {
+ LOGI("Outlier is detected.");
+
+ numExpressiveDirection = idxWithMaxDistance;
+ }
+
+ // final direction computing
+ float summPriority = 0.f;
+ for (size_t i = 0u; i < MovingHistoryAmount - 1; ++i)
+ {
+ if ((int)i != numExpressiveDirection)
+ {
+ directions[j].x += trackDirections[i].x * m_priorities[i];
+ directions[j].y += trackDirections[i].y * m_priorities[i];
+ summPriority += m_priorities[i];
+ }
+ }
+ if (numExpressiveDirection == MovingHistoryAmount - 1)
+ {
+ expressiveTime = true;
+ }
+
+ summPriorityWithoutToLastPos[j] = summPriority;
+ priorityToLastPos[j] = m_priorities[MovingHistoryAmount - 1];
+
+ directions[j].x -= directionsToLastPos[j].x =
+ (m_lastStabilizedContour[j].x -
+ m_movingHistory[MovingHistoryAmount - 1][j].x) *
+ priorityToLastPos[j];
+
+ directions[j].y -= directionsToLastPos[j].y =
+ (m_lastStabilizedContour[j].y -
+ m_movingHistory[MovingHistoryAmount - 1][j].y) *
+ priorityToLastPos[j];
+
+ summPriority += priorityToLastPos[j];
+
+ directions[j].x /= summPriority;
+ directions[j].y /= summPriority;
+ }
+
+ // final corners computing
+ for (size_t j = 0u; j < NumberOfQuadrangleCorners; ++j)
+ {
+ if (expressiveTime)
+ {
+ directions[j].x *= (summPriorityWithoutToLastPos[j] +
+ priorityToLastPos[j]);
+ directions[j].x -= directionsToLastPos[j].x;
+ directions[j].x /= summPriorityWithoutToLastPos[j];
+
+ directions[j].y *= (summPriorityWithoutToLastPos[j] +
+ priorityToLastPos[j]);
+ directions[j].y -= directionsToLastPos[j].y;
+ directions[j].y /= summPriorityWithoutToLastPos[j];
+ }
+
+ stabilizedState[j].x = m_lastStabilizedContour[j].x + directions[j].x;
+ stabilizedState[j].y = m_lastStabilizedContour[j].y + directions[j].y;
+ }
+
+ return stabilizedState;
+}
+
+} /* Image */
+} /* MediaVision */
diff --git a/mv_image/image/src/ImageMathUtil.cpp b/mv_image/image/src/ImageMathUtil.cpp
new file mode 100644
index 00000000..8bf5ba83
--- /dev/null
+++ b/mv_image/image/src/ImageMathUtil.cpp
@@ -0,0 +1,59 @@
+/**
+ * Copyright (c) 2015 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 "ImageMathUtil.h"
+
+namespace MediaVision
+{
+namespace Image
+{
+
+float getDistance(
+ const cv::Point2f& point1,
+ const cv::Point2f& point2)
+{
+ return sqrt(
+ (point1.x - point2.x) * (point1.x - point2.x) +
+ (point1.y - point2.y) * (point1.y - point2.y));
+}
+
+float getTriangleArea(
+ const cv::Point2f& point1,
+ const cv::Point2f& point2,
+ const cv::Point2f& point3)
+{
+ float distances[3];
+
+ distances[0] = getDistance(point1, point2);
+ distances[1] = getDistance(point2, point3);
+ distances[2] = getDistance(point3, point1);
+
+ const float semiperimeter = (distances[0] + distances[1] + distances[2]) / 2.0f;
+
+ return sqrt(semiperimeter *
+ (semiperimeter - distances[0]) *
+ (semiperimeter - distances[1]) *
+ (semiperimeter - distances[2]));
+}
+
+float getQuadrangleArea(const cv::Point2f points[NumberOfQuadrangleCorners])
+{
+ return getTriangleArea(points[0], points[1], points[2]) +
+ getTriangleArea(points[0], points[3], points[2]);
+}
+
+} /* Image */
+} /* MediaVision */
diff --git a/mv_image/image/src/ImageObject.cpp b/mv_image/image/src/ImageObject.cpp
new file mode 100644
index 00000000..531ec62d
--- /dev/null
+++ b/mv_image/image/src/ImageObject.cpp
@@ -0,0 +1,475 @@
+/**
+ * Copyright (c) 2015 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 "ImageObject.h"
+
+#include "ImageMathUtil.h"
+
+#include <app_common.h>
+
+#include "mv_private.h"
+#include "mv_common.h"
+
+#include <opencv/cv.h>
+#include <opencv2/features2d/features2d.hpp>
+
+#include <fstream>
+#include <unistd.h>
+
+namespace MediaVision
+{
+namespace Image
+{
+
+ImageObject::ImageObject() :
+ m_isEmpty(true),
+ m_isLabeled(false),
+ m_label(0),
+ m_recognitionRate(0.f)
+{
+ ; /* NULL */
+}
+
+ImageObject::ImageObject(const cv::Mat& image, const FeaturesExtractingParams& params) :
+ m_isEmpty(true),
+ m_isLabeled(false),
+ m_label(0),
+ m_recognitionRate(0.f)
+{
+ fill(image, params);
+}
+
+ImageObject::ImageObject(const ImageObject& copy) :
+ m_isEmpty(copy.m_isEmpty),
+ m_isLabeled(copy.m_isLabeled),
+ m_label(copy.m_label),
+ m_boundingContour(copy.m_boundingContour),
+ m_objectKeypoints(copy.m_objectKeypoints),
+ m_objectDescriptors(copy.m_objectDescriptors.clone()),
+ m_recognitionRate(copy.m_recognitionRate)
+{
+ ; /* NULL */
+}
+
+ImageObject& ImageObject::operator=(const ImageObject& copy)
+{
+ if (this != &copy)
+ {
+ m_isEmpty = copy.m_isEmpty;
+ m_isLabeled = copy.m_isLabeled;
+ m_label = copy.m_label;
+ m_boundingContour = copy.m_boundingContour;
+ m_objectKeypoints = copy.m_objectKeypoints;
+ m_objectDescriptors = copy.m_objectDescriptors.clone();
+ m_recognitionRate = copy.m_recognitionRate;
+ }
+ return *this;
+}
+
+ImageObject::~ImageObject()
+{
+ ; /* NULL */
+}
+
+void ImageObject::fill(const cv::Mat& image, const FeaturesExtractingParams& params)
+{
+ m_isEmpty = false;
+ m_boundingContour.resize(NumberOfQuadrangleCorners);
+
+ m_boundingContour[0].x = 0.f;
+ m_boundingContour[0].y = 0.f;
+
+ m_boundingContour[1].x = image.cols;
+ m_boundingContour[1].y = 0.f;
+
+ m_boundingContour[2].x = image.cols;
+ m_boundingContour[2].y = image.rows;
+
+ m_boundingContour[3].x = 0.f;
+ m_boundingContour[3].y = image.rows;
+
+ extractFeatures(image, params);
+
+ computeRecognitionRate(image);
+
+ LOGI("[%s] Image object is filled.", __FUNCTION__);
+}
+
+bool ImageObject::fill(const cv::Mat& image, const cv::Rect& boundingBox,
+ const FeaturesExtractingParams& params)
+{
+ if ((0 > boundingBox.x) || (0 >= boundingBox.width) ||
+ (0 > boundingBox.y) || (0 >= boundingBox.height) ||
+ (image.cols < (boundingBox.x + boundingBox.width)) ||
+ (image.rows < (boundingBox.y + boundingBox.height)))
+ {
+ LOGE("[%s] Invalid ROI.", __FUNCTION__);
+ return false;
+ }
+
+ m_isEmpty = false;
+ m_boundingContour.resize(NumberOfQuadrangleCorners);
+
+ m_boundingContour[0].x = 0.f;
+ m_boundingContour[0].y = 0.f;
+
+ m_boundingContour[1].x = boundingBox.width;
+ m_boundingContour[1].y = 0.f;
+
+ m_boundingContour[2].x = boundingBox.width;
+ m_boundingContour[2].y = boundingBox.height;
+
+ m_boundingContour[3].x = 0.f;
+ m_boundingContour[3].y = boundingBox.height;
+
+ cv::Mat objectImage(image, boundingBox);
+
+ extractFeatures(objectImage, params);
+
+ computeRecognitionRate(image);
+
+ LOGI("[%s] Image object is filled.", __FUNCTION__);
+
+ return true;
+}
+
+void ImageObject::extractFeatures(const cv::Mat& image,
+ const FeaturesExtractingParams& params)
+{
+ cv::ORB orb(params.mMaximumFeaturesNumber, params.mScaleFactor);
+
+ if (image.cols < MinWidth || image.rows < MinHeight)
+ {
+ LOGW("[%s] Area is too small, recognition rate is 0.", __FUNCTION__);
+ m_objectKeypoints.clear();
+ m_objectDescriptors = cv::Mat();
+ }
+ else
+ {
+ orb.detect(image, m_objectKeypoints);
+ orb.compute(image, m_objectKeypoints, m_objectDescriptors);
+ }
+}
+
+void ImageObject::computeRecognitionRate(const cv::Mat& image)
+{
+ const size_t numberOfKeypoints = m_objectKeypoints.size();
+
+ // it is impossible to calculate the perspective transformation parameters
+ // if number of key points less than MinimumNumberOfFeatures (4)
+ if (numberOfKeypoints < MinimumNumberOfFeatures)
+ {
+ m_recognitionRate = 0.f;
+ return;
+ }
+
+ static const size_t xCellsNumber = 10u;
+ static const size_t yCellsNumber = 10u;
+
+ cv::Mat cells[xCellsNumber][yCellsNumber];
+ size_t accumulationCounter[xCellsNumber][yCellsNumber];
+
+ const size_t cellWidth = image.cols / xCellsNumber;
+ const size_t cellHeight = image.rows / yCellsNumber;
+
+ for (size_t x = 0u; x < xCellsNumber; ++x)
+ {
+ for (size_t y = 0u; y < yCellsNumber; ++y)
+ {
+ cells[x][y] = image(cv::Rect(
+ x * cellWidth,
+ y * cellHeight,
+ cellWidth,
+ cellHeight));
+
+ accumulationCounter[x][y] = 0;
+ }
+ }
+
+ for (size_t i = 0u; i < numberOfKeypoints; ++i)
+ {
+ size_t xCellIdx = m_objectKeypoints[i].pt.x / cellWidth;
+ if (xCellIdx >= xCellsNumber)
+ {
+ xCellIdx = xCellsNumber - 1;
+ }
+ size_t yCellIdx = m_objectKeypoints[i].pt.y / cellHeight;
+ if (yCellIdx >= yCellsNumber)
+ {
+ yCellIdx = yCellsNumber - 1;
+ }
+ ++(accumulationCounter[xCellIdx][yCellIdx]);
+ }
+
+ const float exceptedNumber = numberOfKeypoints /
+ (float)(xCellsNumber * yCellsNumber);
+
+ float distributedEvaluation = 0.f;
+
+ for (size_t x = 0u; x < xCellsNumber; ++x)
+ {
+ for (size_t y = 0u; y < yCellsNumber; ++y)
+ {
+ distributedEvaluation += (accumulationCounter[x][y] - exceptedNumber) *
+ (accumulationCounter[x][y] - exceptedNumber) / exceptedNumber;
+ }
+ }
+
+ float maximumDistributedEvaluation = (xCellsNumber * yCellsNumber - 1) *
+ exceptedNumber;
+
+ maximumDistributedEvaluation += (numberOfKeypoints - exceptedNumber) *
+ (numberOfKeypoints - exceptedNumber) / exceptedNumber;
+
+ distributedEvaluation = 1 -
+ (distributedEvaluation / maximumDistributedEvaluation);
+
+ // Exponentiation to find an approximate confidence value based on the
+ // number of key points on the image.
+ const float cardinalityEvaluation = pow(-0.9, numberOfKeypoints - 3) + 1.0f;
+
+ m_recognitionRate =
+ distributedEvaluation *
+ cardinalityEvaluation;
+}
+
+float ImageObject::getRecognitionRate(void) const
+{
+ return m_recognitionRate;
+}
+
+bool ImageObject::isEmpty() const
+{
+ return m_isEmpty;
+}
+
+void ImageObject::setLabel(int label)
+{
+ m_isLabeled = true;
+ m_label = label;
+}
+
+bool ImageObject::getLabel(int& label) const
+{
+ if (!m_isLabeled)
+ {
+ LOGW("[%s] Image hasn't label.", __FUNCTION__);
+ return false;
+ }
+ label = m_label;
+ return true;
+}
+
+int ImageObject::save(const char *fileName) const
+{
+ std::string prefix_path = std::string(app_get_data_path());
+ LOGD("prefix_path: %s", prefix_path.c_str());
+
+ std::string filePath;
+ filePath += prefix_path;
+ filePath += fileName;
+
+ /* check the directory is available */
+ std::string prefix_path_check = filePath.substr(0, filePath.find_last_of('/'));
+ if (access(prefix_path_check.c_str(), F_OK))
+ {
+ LOGE("Can't save image object. Path[%s] doesn't existed.", prefix_path_check.c_str());
+
+ return MEDIA_VISION_ERROR_INVALID_PATH;
+ }
+
+ std::ofstream out;
+
+ out.open(filePath.c_str());
+
+ if (!out.is_open())
+ {
+ LOGE("[%s] Can't create/open file.", __FUNCTION__);
+ return MEDIA_VISION_ERROR_PERMISSION_DENIED;
+ }
+
+ out<<(*this);
+
+ out.close();
+ LOGI("[%s] Image object is saved.", __FUNCTION__);
+
+ return MEDIA_VISION_ERROR_NONE;
+}
+
+int ImageObject::load(const char *fileName)
+{
+ /* find directory */
+ std::string prefix_path = std::string(app_get_data_path());
+ LOGD("prefix_path: %s", prefix_path.c_str());
+
+ std::string filePath;
+ filePath += prefix_path;
+ filePath += fileName;
+
+ if (access(filePath.c_str(), F_OK))
+ {
+ LOGE("Can't load image object model. Path[%s] doesn't existed.", filePath.c_str());
+
+ return MEDIA_VISION_ERROR_INVALID_PATH;
+ }
+
+ std::ifstream in;
+ in.open(filePath.c_str());
+
+ if (!in.is_open())
+ {
+ LOGE("[%s] Can't open file.", __FUNCTION__);
+ return MEDIA_VISION_ERROR_PERMISSION_DENIED;
+ }
+
+ in>>(*this);
+
+ if (!in.good())
+ {
+ LOGE("[%s] Unexpected end of file.", __FUNCTION__);
+ return MEDIA_VISION_ERROR_PERMISSION_DENIED;
+ }
+
+ in.close();
+ LOGI("[%s] Image object is loaded.", __FUNCTION__);
+
+ return MEDIA_VISION_ERROR_NONE;
+}
+
+std::ostream& operator << (std::ostream& os, const ImageObject& obj)
+{
+ os<<std::setprecision(7);
+
+ os<<obj.m_isEmpty<<'\n';
+ os<<obj.m_isLabeled<<'\n';
+ os<<obj.m_label<<'\n';
+
+ os<<obj.m_boundingContour.size()<<'\n';
+ for (size_t pointNum = 0u; pointNum < obj.m_boundingContour.size(); ++pointNum)
+ {
+ os<<obj.m_boundingContour[pointNum].x<<' ';
+ os<<obj.m_boundingContour[pointNum].y<<'\n';
+ }
+
+ os<<obj.m_objectKeypoints.size()<<'\n';
+ for (size_t keypointNum = 0u; keypointNum < obj.m_objectKeypoints.size();++keypointNum)
+ {
+ os<<obj.m_objectKeypoints[keypointNum].pt.x<<' ';
+ os<<obj.m_objectKeypoints[keypointNum].pt.y<<' ';
+ os<<obj.m_objectKeypoints[keypointNum].size<<' ';
+ os<<obj.m_objectKeypoints[keypointNum].response<<' ';
+ os<<obj.m_objectKeypoints[keypointNum].angle<<' ';
+ os<<obj.m_objectKeypoints[keypointNum].octave<<' ';
+ os<<obj.m_objectKeypoints[keypointNum].class_id<<'\n';
+ }
+
+ os<<obj.m_objectDescriptors.rows<<' ';
+ os<<obj.m_objectDescriptors.cols<<' ';
+ os<<obj.m_objectDescriptors.type()<<'\n';
+ for (int descriptorNum = 0; descriptorNum < obj.m_objectDescriptors.rows;
+ ++descriptorNum)
+ {
+ for (int featureNum = 0; featureNum < obj.m_objectDescriptors.cols;
+ ++featureNum, os<<'\n')
+ {
+ os<<(int)obj.m_objectDescriptors.at<uchar>(descriptorNum, featureNum)<<' ';
+ }
+ }
+
+ return os;
+}
+
+std::istream& operator >> (std::istream& is, ImageObject& obj)
+{
+ size_t numberOfContourPoints = 0u;
+ size_t numberOfKeyPoints = 0u;
+ int rows = 0, cols = 0;
+ int descriptorType = 0;
+
+ ImageObject temporal;
+
+#define MEDIA_VISION_CHECK_IFSTREAM \
+ if (!is.good()) \
+ { \
+ return is; \
+ }
+
+ is>>temporal.m_isEmpty;
+ MEDIA_VISION_CHECK_IFSTREAM
+ is>>temporal.m_isLabeled;
+ MEDIA_VISION_CHECK_IFSTREAM
+ is>>temporal.m_label;
+ MEDIA_VISION_CHECK_IFSTREAM
+
+ is>>numberOfContourPoints;
+ MEDIA_VISION_CHECK_IFSTREAM
+
+ temporal.m_boundingContour.resize(numberOfContourPoints);
+ for (size_t pointNum = 0; pointNum < temporal.m_boundingContour.size(); ++pointNum)
+ {
+ is>>temporal.m_boundingContour[pointNum].x;
+ MEDIA_VISION_CHECK_IFSTREAM
+ is>>temporal.m_boundingContour[pointNum].y;
+ MEDIA_VISION_CHECK_IFSTREAM
+ }
+
+ is>>numberOfKeyPoints;
+ temporal.m_objectKeypoints.resize(numberOfKeyPoints);
+ for (size_t keypointNum = 0; keypointNum < temporal.m_objectKeypoints.size(); ++keypointNum)
+ {
+ is>>temporal.m_objectKeypoints[keypointNum].pt.x;
+ MEDIA_VISION_CHECK_IFSTREAM
+ is>>temporal.m_objectKeypoints[keypointNum].pt.y;
+ MEDIA_VISION_CHECK_IFSTREAM
+ is>>temporal.m_objectKeypoints[keypointNum].size;
+ MEDIA_VISION_CHECK_IFSTREAM
+ is>>temporal.m_objectKeypoints[keypointNum].response;
+ MEDIA_VISION_CHECK_IFSTREAM
+ is>>temporal.m_objectKeypoints[keypointNum].angle;
+ MEDIA_VISION_CHECK_IFSTREAM
+ is>>temporal.m_objectKeypoints[keypointNum].octave;
+ MEDIA_VISION_CHECK_IFSTREAM
+ is>>temporal.m_objectKeypoints[keypointNum].class_id;
+ MEDIA_VISION_CHECK_IFSTREAM
+ }
+
+ is>>rows;
+ MEDIA_VISION_CHECK_IFSTREAM
+ is>>cols;
+ MEDIA_VISION_CHECK_IFSTREAM
+ is>>descriptorType;
+ MEDIA_VISION_CHECK_IFSTREAM
+ temporal.m_objectDescriptors = cv::Mat(rows, cols, descriptorType);
+ int value = 0;
+ for (int descriptorNum = 0; descriptorNum < temporal.m_objectDescriptors.rows; ++descriptorNum)
+ {
+ for (int featureNum = 0; featureNum < temporal.m_objectDescriptors.cols; ++featureNum)
+ {
+ is>>value;
+ MEDIA_VISION_CHECK_IFSTREAM
+ temporal.m_objectDescriptors.at<uchar>(descriptorNum, featureNum) = (uchar)value;
+ }
+ }
+
+#undef MEDIA_VISION_CHECK_IFSTREAM
+
+ obj = temporal;
+
+ return is;
+}
+
+} /* Image */
+} /* MediaVision */
diff --git a/mv_image/image/src/ImageRecognizer.cpp b/mv_image/image/src/ImageRecognizer.cpp
new file mode 100644
index 00000000..c9215556
--- /dev/null
+++ b/mv_image/image/src/ImageRecognizer.cpp
@@ -0,0 +1,312 @@
+/**
+ * Copyright (c) 2015 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 "ImageRecognizer.h"
+#include "ImageObject.h"
+
+#include "mv_private.h"
+
+namespace MediaVision
+{
+namespace Image
+{
+
+ImageRecognizer::ImageRecognizer(
+ const cv::Mat& sceneImage,
+ const FeaturesExtractingParams& params) :
+ m_scene(sceneImage, params)
+{
+ ; /* NULL */
+}
+
+ImageRecognizer::ImageRecognizer(const ImageObject& scene) :
+ m_scene(scene)
+{
+ ; /* NULL */
+}
+
+ImageRecognizer::~ImageRecognizer()
+{
+ ; /* NULL */
+}
+
+bool ImageRecognizer::recognize(
+ const ImageObject& target,
+ const RecognitionParams& params,
+ std::vector<cv::Point2f>& contour) const
+{
+ cv::Mat homophraphyMatrix;
+
+ contour.clear();
+
+ if (MinimumNumberOfFeatures > target.m_objectKeypoints.size())
+ {
+ LOGW("[%s] Image object can't be recognized (Recognition rate is too small).", __FUNCTION__);
+ return false;
+ }
+ if (MinimumNumberOfFeatures > m_scene.m_objectKeypoints.size())
+ {
+ LOGW("[%s] Scene image can't be analyzed (Too few features for recognition).", __FUNCTION__);
+ return false;
+ }
+
+ if(!findHomophraphyMatrix(target, params, homophraphyMatrix))
+ {
+ LOGE("[%s] Can't match the features.", __FUNCTION__);
+ return false;
+ }
+
+ cv::perspectiveTransform(target.m_boundingContour, contour, homophraphyMatrix);
+
+ if (target.m_boundingContour.size() == NumberOfQuadrangleCorners)
+ {
+ if (!isPossibleQuadrangleCorners(contour.data()))
+ {
+ LOGI("[%s] Image object isn't recognized.", __FUNCTION__);
+ contour.clear();
+ return false;
+ }
+ }
+
+ LOGI("[%s] Image object is recognized.", __FUNCTION__);
+ return true;
+}
+
+bool ImageRecognizer::findHomophraphyMatrix(
+ const ImageObject& target,
+ const RecognitionParams& params,
+ cv::Mat& homophraphyMatrix) const
+{
+ std::vector<cv::DMatch> matches;
+
+ m_matcher.match(target.m_objectDescriptors, m_scene.m_objectDescriptors, matches);
+
+ size_t matchesNumber = matches.size();
+
+ if (MinimumNumberOfFeatures > matchesNumber)
+ {
+ LOGE("[%s] Can't match the features.", __FUNCTION__);
+ return false;
+ }
+
+ size_t requiredMatchesNumber =
+ params.mRequiredMatchesPart * matchesNumber;
+
+ size_t allowableMatchesNumberError =
+ params.mAllowableMatchesPartError * requiredMatchesNumber;
+
+ if (matchesNumber - allowableMatchesNumberError >
+ (size_t)params.mMinMatchesNumber &&
+ requiredMatchesNumber + allowableMatchesNumberError <
+ matchesNumber)
+ {
+ if (requiredMatchesNumber - allowableMatchesNumberError <
+ (size_t)params.mMinMatchesNumber)
+ {
+ if (requiredMatchesNumber + allowableMatchesNumberError >
+ (size_t)params.mMinMatchesNumber)
+ {
+ requiredMatchesNumber = ((size_t)params.mMinMatchesNumber +
+ requiredMatchesNumber + allowableMatchesNumberError) / 2;
+
+ allowableMatchesNumberError = requiredMatchesNumber-
+ (size_t)params.mMinMatchesNumber +
+ allowableMatchesNumberError;
+ }
+ else
+ {
+ const size_t minimalAllowableMatchesNumberError = 2u;
+
+ requiredMatchesNumber = params.mMinMatchesNumber +
+ minimalAllowableMatchesNumberError;
+
+ allowableMatchesNumberError = minimalAllowableMatchesNumberError;
+ }
+ }
+
+ const size_t filterAmount = matchesSelection(matches,
+ requiredMatchesNumber,
+ allowableMatchesNumberError);
+
+ if (filterAmount >= MinimumNumberOfFeatures)
+ {
+ matches.resize(filterAmount);
+ }
+ else
+ {
+ LOGW("[%s] Wrong filtration of feature matches.", __FUNCTION__);
+ }
+
+ matchesNumber = matches.size();
+ }
+
+ std::vector<cv::Point2f> objectPoints(matchesNumber);
+ std::vector<cv::Point2f> scenePoints(matchesNumber);
+
+ for (size_t matchIdx = 0; matchIdx < matchesNumber; ++matchIdx)
+ {
+ objectPoints[matchIdx] =
+ target.m_objectKeypoints[matches[matchIdx].queryIdx].pt;
+
+ scenePoints[matchIdx] =
+ m_scene.m_objectKeypoints[matches[matchIdx].trainIdx].pt;
+ }
+
+ homophraphyMatrix = cv::findHomography(objectPoints, scenePoints, CV_RANSAC);
+
+ return true;
+}
+
+size_t ImageRecognizer::matchesSelection(
+ std::vector<cv::DMatch>& examples,
+ unsigned int filterAmount, unsigned int allowableError) const
+{
+ size_t sizeOfExamples = examples.size();
+
+ if ((filterAmount + allowableError) > sizeOfExamples)
+ {
+ return examples.size();
+ }
+
+ int startLeftLimit = 0;
+ int startRightLimit = sizeOfExamples - 1;
+
+ int leftLimit = startLeftLimit;
+ int rightLimit = startRightLimit;
+
+ int requiredNumber = filterAmount;
+
+ float supportElement = 0.f;
+
+ while (true)
+ {
+ if (leftLimit >= rightLimit)
+ {
+ if (leftLimit < (requiredNumber - (int)allowableError))
+ {
+ leftLimit = requiredNumber + (int)allowableError;
+ }
+
+ break;
+ }
+
+ supportElement = computeLinearSupportElement(examples, requiredNumber,
+ leftLimit, rightLimit);
+
+ // Iteration similar quicksort
+ while (true)
+ {
+ // Search the leftmost element which have bigger confidence than support element
+ while (examples[leftLimit].distance <= supportElement &&
+ leftLimit < startRightLimit)
+ {
+ ++leftLimit;
+ }
+
+ // Search the rightmost element which have smaller confidence than support element
+ while (examples[rightLimit].distance >= supportElement &&
+ rightLimit >= startLeftLimit)
+ {
+ --rightLimit;
+ }
+
+ if (leftLimit >= rightLimit)
+ {
+ break;
+ }
+
+ // Swap
+ std::swap(examples[leftLimit], examples[rightLimit]);
+ }
+ if (abs(filterAmount - leftLimit) <= (int)allowableError)
+ {
+ break;
+ }
+ if ((int)filterAmount > leftLimit)
+ {
+ requiredNumber -= leftLimit - startLeftLimit;
+
+ rightLimit = startRightLimit;
+ startLeftLimit = leftLimit;
+ }
+ else
+ {
+ leftLimit = startLeftLimit;
+ startRightLimit = rightLimit;
+ }
+ }
+
+ return (size_t)leftLimit;
+}
+
+float ImageRecognizer::computeLinearSupportElement(const std::vector<cv::DMatch>& examples,
+ int requiredNumber, int leftLimit, int rightLimit) const
+{
+ int sizeOfExamples = rightLimit - leftLimit + 1;
+
+ if (sizeOfExamples <= 1)
+ {
+ return examples[leftLimit].distance;
+ }
+
+ float minValue = examples[leftLimit].distance;
+ float maxValue = examples[leftLimit].distance;
+
+ // Finding the maximum and minimum values
+ for (int i = leftLimit + 1; i <= rightLimit; ++i)
+ {
+ if (minValue > examples[i].distance)
+ {
+ minValue = examples[i].distance;
+ }
+ else if (maxValue < examples[i].distance)
+ {
+ maxValue = examples[i].distance;
+ }
+ }
+
+ // Linear approximation. f(x) = k*x + b
+ // f(sizeOfExamples) = maxValue; f(1) = minValue;
+ const float b = (maxValue - minValue * sizeOfExamples) / (1 - sizeOfExamples);
+ const float k = minValue - b;
+
+ // Calculation of the support element
+ return k * requiredNumber + b;
+}
+
+bool ImageRecognizer::isPossibleQuadrangleCorners(
+ const cv::Point2f corners[NumberOfQuadrangleCorners])
+{
+ static const float Epsilon = cv::TermCriteria::EPS;
+ static const float MinSizeOfDetectedArea = 30.f;
+
+ const float firstSemiArea = getTriangleArea(corners[0], corners[2], corners[1]) +
+ getTriangleArea(corners[0], corners[2], corners[3]);
+
+ const float secondSemiArea = getTriangleArea(corners[1], corners[3], corners[2]) +
+ getTriangleArea(corners[1], corners[3], corners[0]);
+
+ if (Epsilon < fabs(firstSemiArea - secondSemiArea) ||
+ MinSizeOfDetectedArea > (firstSemiArea + secondSemiArea))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+} /* Image */
+} /* MediaVision */
diff --git a/mv_image/image/src/ImageTracker.cpp b/mv_image/image/src/ImageTracker.cpp
new file mode 100644
index 00000000..9c114f58
--- /dev/null
+++ b/mv_image/image/src/ImageTracker.cpp
@@ -0,0 +1,372 @@
+/**
+ * Copyright (c) 2015 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 "ImageTracker.h"
+
+#include "ImageMathUtil.h"
+#include "ImageRecognizer.h"
+#include "ImageTrackingModel.h"
+#include "ImageContourStabilizator.h"
+
+#include "mv_private.h"
+
+#include <pthread.h>
+
+namespace MediaVision
+{
+namespace Image
+{
+
+ImageTracker::ImageTracker(const TrackingParams& trackingParams) :
+ m_trackingParams(trackingParams)
+{
+ ; /* NULL */
+}
+
+void ImageTracker::track(const cv::Mat& frame, ImageTrackingModel& target)
+{
+ ImageTrackingModel::State currentState = ImageTrackingModel::Undetected;
+
+ while (pthread_mutex_trylock(&target.m_globalGuard) != 0)
+ {
+ pthread_spin_lock(&target.m_stateGuard);
+ currentState = target.m_state;
+ pthread_spin_unlock(&target.m_stateGuard);
+
+ if (ImageTrackingModel::InProcess == currentState)
+ {
+ LOGI("[%s] Calling is skipped. Object is recognizing.", __FUNCTION__);
+ return;
+ }
+ }
+
+ pthread_spin_lock(&target.m_stateGuard);
+ currentState = target.m_state;
+ pthread_spin_unlock(&target.m_stateGuard);
+
+ if (ImageTrackingModel::Invalid == currentState)
+ {
+ pthread_mutex_unlock(&target.m_globalGuard);
+ LOGE("[%s] Tracking model is invalid.", __FUNCTION__);
+ return;
+ }
+
+ switch (target.m_state)
+ {
+ case ImageTrackingModel::Appeared:
+ case ImageTrackingModel::Tracked:
+ {
+ pthread_spin_lock(&target.m_stateGuard);
+ target.m_state = ImageTrackingModel::InProcess;
+ pthread_spin_unlock(&target.m_stateGuard);
+
+ trackDetectedObject(frame, target);
+ break;
+ }
+ case ImageTrackingModel::Undetected:
+ {
+ pthread_spin_lock(&target.m_stateGuard);
+ target.m_state = ImageTrackingModel::InProcess;
+ pthread_spin_unlock(&target.m_stateGuard);
+
+ trackUndetectedObject(frame, target);
+
+ // Recognition thread is started. Don't use target here, just exit!
+ return;
+ }
+ case ImageTrackingModel::InProcess:
+ default:
+ {
+ // Abnormal behaviour:
+ // tracking model state is InProcess but globalGuard is not locked
+ LOGE("[%s] Abnormal behaviour. Tracking model status is"
+ "\"InProgress\" but it is not in progress.", __FUNCTION__);
+
+ pthread_spin_lock(&target.m_stateGuard);
+ if (target.m_recognitionObject.isEmpty())
+ {
+ target.m_state = ImageTrackingModel::Invalid;
+ LOGI("[%s] Tracking model status is changed on \"Invalid\"", __FUNCTION__);
+ }
+ else
+ {
+ target.m_state = ImageTrackingModel::Undetected;
+ LOGI("[%s] Tracking model status is changed on \"Undetected\"", __FUNCTION__);
+ }
+ pthread_spin_unlock(&target.m_stateGuard);
+
+ pthread_mutex_unlock(&target.m_globalGuard);
+ break;
+ }
+ }
+}
+
+void ImageTracker::trackDetectedObject(
+ const cv::Mat& frame,
+ ImageTrackingModel& target)
+{
+ cv::Rect expectedArea = computeExpectedArea(target, frame.size());
+
+ std::vector<cv::Point2f> resultContour;
+
+ ImageRecognizer recognizer(
+ frame(expectedArea),
+ m_trackingParams.mFramesFeaturesExtractingParams);
+
+ const bool isRecognized = recognizer.recognize(
+ target.m_recognitionObject,
+ m_trackingParams.mRecognitionParams,
+ resultContour);
+
+ if (isRecognized)
+ {
+ for (size_t pointIdx = 0; pointIdx < resultContour.size(); ++pointIdx)
+ {
+ resultContour[pointIdx].x += expectedArea.x;
+ resultContour[pointIdx].y += expectedArea.y;
+ }
+
+ if (m_trackingParams.mStabilizationParams.mHistoryAmount > 0)
+ {
+ target.m_stabilizator.stabilize(
+ resultContour,
+ m_trackingParams.mStabilizationParams);
+ }
+
+ target.m_stabilizator.stabilize(
+ resultContour,
+ m_trackingParams.mStabilizationParams);
+
+ pthread_spin_lock(&target.m_lastLocationGuard);
+ target.m_lastLocation = resultContour;
+ pthread_spin_unlock(&target.m_lastLocationGuard);
+
+ pthread_spin_lock(&target.m_stateGuard);
+ target.m_state = ImageTrackingModel::Tracked;
+ pthread_spin_unlock(&target.m_stateGuard);
+
+ LOGI("[%s] Object is successfully tracked.", __FUNCTION__);
+ }
+ else
+ {
+ target.m_stabilizator.reset();
+
+ pthread_spin_lock(&target.m_stateGuard);
+ target.m_state = ImageTrackingModel::Undetected;
+ pthread_spin_unlock(&target.m_stateGuard);
+
+ LOGI("[%s] Object is lost.", __FUNCTION__);
+ }
+
+ pthread_mutex_unlock(&target.m_globalGuard);
+}
+
+void *ImageTracker::recognitionThreadFunc(void *recognitionInfo)
+{
+ if (NULL == recognitionInfo)
+ {
+ return NULL;
+ }
+
+ RecognitionInfo *recogInfo = (RecognitionInfo*)recognitionInfo;
+
+ std::vector<cv::Point2f> resultContour;
+
+ ImageRecognizer recognizer(
+ recogInfo->mFrame,
+ recogInfo->mSceneFeaturesExtractingParams);
+
+ bool isRecognized = recognizer.recognize(
+ recogInfo->mpTarget->m_recognitionObject,
+ recogInfo->mRecognitionParams,
+ resultContour);
+
+ if (isRecognized)
+ {
+ recogInfo->mpTarget->m_stabilizator.reset();
+
+ pthread_spin_lock(&(recogInfo->mpTarget->m_lastLocationGuard));
+ recogInfo->mpTarget->m_lastLocation = resultContour;
+ pthread_spin_unlock(&(recogInfo->mpTarget->m_lastLocationGuard));
+
+ pthread_spin_lock(&(recogInfo->mpTarget->m_stateGuard));
+ recogInfo->mpTarget->m_state = ImageTrackingModel::Appeared;
+ pthread_spin_unlock(&(recogInfo->mpTarget->m_stateGuard));
+ }
+ else
+ {
+ pthread_spin_lock(&(recogInfo->mpTarget->m_stateGuard));
+ recogInfo->mpTarget->m_state = ImageTrackingModel::Undetected;
+ pthread_spin_unlock(&(recogInfo->mpTarget->m_stateGuard));
+ }
+
+ recogInfo->mpTarget->m_recognitionThread = 0;
+
+ pthread_mutex_unlock(&(recogInfo->mpTarget->m_globalGuard));
+
+ delete recogInfo;
+
+ return NULL;
+}
+
+void ImageTracker::trackUndetectedObject(
+ const cv::Mat& frame,
+ ImageTrackingModel& target)
+{
+ RecognitionInfo *recognitionInfo = new RecognitionInfo;
+
+ recognitionInfo->mFrame = frame.clone();
+ recognitionInfo->mpTarget = &target;
+
+ recognitionInfo->mRecognitionParams =
+ m_trackingParams.mRecognitionParams;
+ recognitionInfo->mSceneFeaturesExtractingParams =
+ m_trackingParams.mFramesFeaturesExtractingParams;
+
+ if (target.m_recognitionThread)
+ {
+ // Abnormal behaviour:
+ // Recognition thread isn't finished but guardian mutex is unlocked
+ LOGE("[%s] Abnormal behaviour. Recognition thread isn't finished but"
+ "guardian mutex is unlocked.", __FUNCTION__);
+
+ LOGI("[%s] Try to wait recognition thread.", __FUNCTION__);
+ pthread_join(target.m_recognitionThread, NULL);
+ target.m_recognitionThread = 0;
+ LOGI("[%s] Recognition thread is finished.", __FUNCTION__);
+ }
+
+ const int err = pthread_create(
+ &target.m_recognitionThread,
+ NULL,
+ recognitionThreadFunc,
+ recognitionInfo);
+
+ if (0 == err)
+ {
+ LOGI("[%s] Recognition thread is started.", __FUNCTION__);
+ // Recognition thread is started. Don't use target here, just exit!
+ return;
+ }
+ LOGE("[%s] Recognition thread creation is failed.", __FUNCTION__);
+
+ pthread_spin_lock(&target.m_stateGuard);
+ if (target.m_recognitionObject.isEmpty())
+ {
+ target.m_state = ImageTrackingModel::Invalid;
+ LOGI("[%s] Tracking model status is changed on \"Invalid\"", __FUNCTION__);
+ }
+ else
+ {
+ target.m_state = ImageTrackingModel::Undetected;
+ LOGI("[%s] Tracking model status is changed on \"Undetected\"", __FUNCTION__);
+ }
+ pthread_spin_unlock(&target.m_stateGuard);
+
+ pthread_mutex_unlock(&target.m_globalGuard);
+}
+
+cv::Rect ImageTracker::computeExpectedArea(
+ const ImageTrackingModel& target,
+ const cv::Size& frameSize)
+{
+ if (target.m_state == ImageTrackingModel::Appeared)
+ {
+ LOGI("[%s] Expected area for appeared object is full frame.", __FUNCTION__);
+ return cv::Rect(0, 0, frameSize.width, frameSize.height);
+ }
+
+ if (target.m_lastLocation.empty())
+ {
+ LOGW("[%s] Can't compute expected area for object without last"
+ "location.",__FUNCTION__);
+ return cv::Rect(0, 0, 0, 0);
+ }
+
+ cv::Point2f ltCorner(target.m_lastLocation[0]);
+ cv::Point2f rbCorner(target.m_lastLocation[0]);
+
+ const size_t contourPointsNumber = target.m_lastLocation.size();
+
+ for (size_t pointNum = 1; pointNum < contourPointsNumber; ++pointNum)
+ {
+ if (ltCorner.x > target.m_lastLocation[pointNum].x)
+ {
+ ltCorner.x = target.m_lastLocation[pointNum].x;
+ }
+ else if (rbCorner.x < target.m_lastLocation[pointNum].x)
+ {
+ rbCorner.x = target.m_lastLocation[pointNum].x;
+ }
+
+ if (ltCorner.y > target.m_lastLocation[pointNum].y)
+ {
+ ltCorner.y = target.m_lastLocation[pointNum].y;
+ }
+ else if (rbCorner.y < target.m_lastLocation[pointNum].y)
+ {
+ rbCorner.y = target.m_lastLocation[pointNum].y;
+ }
+ }
+
+ cv::Point2f center(
+ (ltCorner.x + rbCorner.x) / 2.0f,
+ (ltCorner.y + rbCorner.y) / 2.0f);
+
+ cv::Size2f halfSize(
+ (center.x - ltCorner.x) * (1 + m_trackingParams.mExpectedOffset),
+ (center.y - ltCorner.y) * (1 + m_trackingParams.mExpectedOffset));
+
+
+ cv::Rect expectedArea(
+ center.x - halfSize.width, center.y - halfSize.height,
+ halfSize.width * 2, halfSize.height * 2);
+
+ if (expectedArea.x < 0)
+ {
+ expectedArea.width += expectedArea.x;
+ expectedArea.x = 0;
+ }
+
+ if (expectedArea.y < 0)
+ {
+ expectedArea.height += expectedArea.y;
+ expectedArea.y = 0;
+ }
+
+ if (expectedArea.x + expectedArea.width > frameSize.width)
+ {
+ expectedArea.width = frameSize.width - expectedArea.x;
+ }
+
+ if (expectedArea.y + expectedArea.height > frameSize.height)
+ {
+ expectedArea.height = frameSize.height - expectedArea.y;
+ }
+
+ if (expectedArea.width <= 0 || expectedArea.height <= 0)
+ {
+ expectedArea.x = 0;
+ expectedArea.y = 0;
+ expectedArea.width = 0;
+ expectedArea.height = 0;
+ }
+
+ return expectedArea;
+}
+
+} /* Image */
+} /* MediaVision */
diff --git a/mv_image/image/src/ImageTrackingModel.cpp b/mv_image/image/src/ImageTrackingModel.cpp
new file mode 100644
index 00000000..e0a75c97
--- /dev/null
+++ b/mv_image/image/src/ImageTrackingModel.cpp
@@ -0,0 +1,365 @@
+/**
+ * Copyright (c) 2015 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 "ImageTrackingModel.h"
+
+#include <app_common.h>
+
+#include "mv_private.h"
+#include "mv_common.h"
+
+#include <fstream>
+#include <unistd.h>
+
+namespace MediaVision
+{
+namespace Image
+{
+
+ImageTrackingModel::ImageTrackingModel() :
+ m_recognitionObject(),
+ m_lastLocation(0),
+ m_state(Invalid),
+ m_recognitionThread(0)
+{
+ pthread_mutex_init(&m_globalGuard, NULL);
+ pthread_spin_init(&m_lastLocationGuard, PTHREAD_PROCESS_SHARED);
+ pthread_spin_init(&m_stateGuard, PTHREAD_PROCESS_SHARED);
+}
+
+ImageTrackingModel::ImageTrackingModel(const ImageObject& recognitionObject) :
+ m_recognitionObject(recognitionObject),
+ m_lastLocation(0),
+ m_state(Invalid),
+ m_recognitionThread(0)
+{
+ if (!recognitionObject.isEmpty())
+ {
+ m_state = Undetected;
+ }
+ pthread_mutex_init(&m_globalGuard, NULL);
+ pthread_spin_init(&m_lastLocationGuard, PTHREAD_PROCESS_SHARED);
+ pthread_spin_init(&m_stateGuard, PTHREAD_PROCESS_SHARED);
+}
+
+ImageTrackingModel::ImageTrackingModel(const ImageTrackingModel& copy) :
+ m_recognitionThread(0)
+{
+ pthread_mutex_init(&m_globalGuard, NULL);
+ pthread_spin_init(&m_lastLocationGuard, PTHREAD_PROCESS_SHARED);
+ pthread_spin_init(&m_stateGuard, PTHREAD_PROCESS_SHARED);
+
+ *this = copy;
+}
+
+ImageTrackingModel::~ImageTrackingModel()
+{
+ if (m_recognitionThread)
+ {
+ pthread_join(m_recognitionThread, NULL);
+ }
+
+ pthread_mutex_destroy(&m_globalGuard);
+ pthread_spin_destroy(&m_lastLocationGuard);
+ pthread_spin_destroy(&m_stateGuard);
+}
+
+void ImageTrackingModel::setTarget(const ImageObject& target)
+{
+ pthread_mutex_lock(&m_globalGuard);
+
+ pthread_spin_lock(&m_stateGuard);
+ m_state = target.isEmpty() ? Invalid : Undetected;
+ pthread_spin_unlock(&m_stateGuard);
+
+ pthread_spin_lock(&m_lastLocationGuard);
+ m_lastLocation.clear();
+ pthread_spin_unlock(&m_lastLocationGuard);
+
+ LOGI("[%s] Target is set into tracking model.", __FUNCTION__);
+
+ m_recognitionObject = target;
+
+ pthread_mutex_unlock(&m_globalGuard);
+}
+
+void ImageTrackingModel::refresh(void)
+{
+ pthread_mutex_lock(&m_globalGuard);
+
+ pthread_spin_lock(&m_stateGuard);
+ m_state = m_recognitionObject.isEmpty() ? Invalid : Undetected;
+ pthread_spin_unlock(&m_stateGuard);
+
+ pthread_spin_lock(&m_lastLocationGuard);
+ m_lastLocation.clear();
+ pthread_spin_unlock(&m_lastLocationGuard);
+
+ LOGI("[%s] Image tracking model is refreshed.", __FUNCTION__);
+
+ pthread_mutex_unlock(&m_globalGuard);
+}
+
+bool ImageTrackingModel::isValid() const
+{
+ bool result = false;
+
+ pthread_spin_lock(&m_stateGuard);
+ result = (m_state != Invalid);
+ pthread_spin_unlock(&m_stateGuard);
+
+ return result;
+}
+
+ImageTrackingModel& ImageTrackingModel::operator=(const ImageTrackingModel& copy)
+{
+ if (this != &copy)
+ {
+ pthread_mutex_t *higherMutex = &m_globalGuard;
+ pthread_mutex_t *lowerMutex = &copy.m_globalGuard;
+
+ if (higherMutex < lowerMutex)
+ {
+ std::swap(higherMutex, lowerMutex);
+ }
+
+ pthread_mutex_lock(higherMutex);
+ pthread_mutex_lock(lowerMutex);
+
+ m_recognitionObject = copy.m_recognitionObject;
+
+ pthread_spin_lock(&m_lastLocationGuard);
+ m_lastLocation = copy.m_lastLocation;
+ pthread_spin_unlock(&m_lastLocationGuard);
+
+ if (copy.m_state == InProcess)
+ {
+ pthread_spin_lock(&m_stateGuard);
+ m_state = m_recognitionObject.isEmpty() ? Invalid : Undetected;
+ pthread_spin_unlock(&m_stateGuard);
+ }
+ else
+ {
+ pthread_spin_lock(&m_stateGuard);
+ m_state = copy.m_state;
+ pthread_spin_unlock(&m_stateGuard);
+ }
+
+ pthread_mutex_unlock(lowerMutex);
+ pthread_mutex_unlock(higherMutex);
+ }
+
+ return *this;
+}
+
+int ImageTrackingModel::save(const char *fileName) const
+{
+ std::string prefix_path = std::string(app_get_data_path());
+ LOGD("prefix_path: %s", prefix_path.c_str());
+
+ std::string filePath;
+ filePath += prefix_path;
+ filePath += fileName;
+
+ /* check the directory is available */
+ std::string prefix_path_check = filePath.substr(0, filePath.find_last_of('/'));
+ if (access(prefix_path_check.c_str(),F_OK))
+ {
+ LOGE("Can't save tracking model. Path[%s] doesn't existed.", prefix_path_check.c_str());
+
+ return MEDIA_VISION_ERROR_INVALID_PATH;
+ }
+
+ std::ofstream out;
+ out.open(filePath.c_str());
+
+ if (!out.is_open())
+ {
+ LOGE("[%s] Can't create/open file.", __FUNCTION__);
+ return MEDIA_VISION_ERROR_PERMISSION_DENIED;
+ }
+
+ out<<(*this);
+
+ out.close();
+ LOGI("[%s] Image tracking model is saved.", __FUNCTION__);
+
+ return MEDIA_VISION_ERROR_NONE;
+}
+
+int ImageTrackingModel::load(const char *fileName)
+{
+ /* find directory */
+ std::string prefix_path = std::string(app_get_data_path());
+ LOGD("prefix_path: %s", prefix_path.c_str());
+
+ std::string filePath;
+ filePath += prefix_path;
+ filePath += fileName;
+
+ if (access(filePath.c_str(),F_OK))
+ {
+ LOGE("Can't load tracking model. Path[%s] doesn't existed.", filePath.c_str());
+
+ return MEDIA_VISION_ERROR_INVALID_PATH;
+ }
+
+ std::ifstream in;
+ in.open(filePath.c_str());
+
+ if (!in.is_open())
+ {
+ LOGE("[%s] Can't open file.", __FUNCTION__);
+ return MEDIA_VISION_ERROR_PERMISSION_DENIED;
+ }
+
+ in>>(*this);
+
+ if (!in.good())
+ {
+ LOGE("[%s] Unexpected end of file.", __FUNCTION__);
+ return MEDIA_VISION_ERROR_PERMISSION_DENIED;
+ }
+
+ in.close();
+ LOGI("[%s] Image tracking model is loaded.", __FUNCTION__);
+
+ return MEDIA_VISION_ERROR_NONE;
+}
+
+bool ImageTrackingModel::isDetected() const
+{
+ bool result = false;
+
+ pthread_spin_lock(&m_stateGuard);
+ result = (m_state == Tracked);
+ pthread_spin_unlock(&m_stateGuard);
+
+ return result;
+}
+
+std::vector<cv::Point2f> ImageTrackingModel::getLastlocation() const
+{
+ std::vector<cv::Point2f> result;
+
+ pthread_spin_lock(&m_lastLocationGuard);
+ result = m_lastLocation;
+ pthread_spin_unlock(&m_lastLocationGuard);
+
+ return result;
+}
+
+#define STATE_UNSEEN_IO_ID 0
+#define STATE_VISIBLE_IO_ID 1
+
+std::ostream& operator << (std::ostream& os, const ImageTrackingModel::State& state)
+{
+ if (ImageTrackingModel::Tracked == state)
+ {
+ os<<STATE_VISIBLE_IO_ID;
+ }
+ else
+ {
+ os<<STATE_UNSEEN_IO_ID;
+ }
+
+ return os;
+}
+
+std::istream& operator >> (std::istream& is, ImageTrackingModel::State& state)
+{
+ int stateId = -1;
+
+ is>>stateId;
+
+ if (STATE_VISIBLE_IO_ID == stateId)
+ {
+ state = ImageTrackingModel::Tracked;
+ }
+ else
+ {
+ state = ImageTrackingModel::Undetected;
+ }
+
+ return is;
+}
+
+#undef STATE_UNSEEN_IO_ID
+#undef STATE_VISIBLE_IO_ID
+
+std::ostream& operator << (std::ostream& os, const ImageTrackingModel& obj)
+{
+ os<<std::setprecision(7);
+
+ pthread_mutex_lock(&obj.m_globalGuard);
+
+ os<<obj.m_recognitionObject;
+
+ os<<obj.m_lastLocation.size();
+ for (size_t pointNum = 0u; pointNum < obj.m_lastLocation.size(); ++pointNum)
+ {
+ os<<' '<<obj.m_lastLocation[pointNum].x<<' '<<obj.m_lastLocation[pointNum].y;
+ }
+ os<<'\n';
+
+ os<<obj.m_state<<'\n';
+
+ pthread_mutex_unlock(&obj.m_globalGuard);
+
+ return os;
+}
+
+std::istream& operator >> (std::istream& is, ImageTrackingModel& obj)
+{
+#define MEDIA_VISION_CHECK_IFSTREAM \
+ if (!is.good()) \
+ { \
+ return is; \
+ }
+
+ ImageTrackingModel temporal;
+
+ is>>obj.m_recognitionObject;
+ MEDIA_VISION_CHECK_IFSTREAM
+
+ size_t lastLocationAmount = 0u;
+ is>>lastLocationAmount;
+ MEDIA_VISION_CHECK_IFSTREAM
+
+ temporal.m_lastLocation.resize(lastLocationAmount);
+ for (size_t pointNum = 0u; pointNum < lastLocationAmount; ++pointNum)
+ {
+ is>>temporal.m_lastLocation[pointNum].x;
+ MEDIA_VISION_CHECK_IFSTREAM
+ is>>temporal.m_lastLocation[pointNum].y;
+ MEDIA_VISION_CHECK_IFSTREAM
+ }
+
+ is>>temporal.m_state;
+ MEDIA_VISION_CHECK_IFSTREAM
+
+ if (temporal.m_recognitionObject.isEmpty())
+ {
+ temporal.m_state = ImageTrackingModel::Invalid;
+ }
+
+ obj = temporal;
+
+ return is;
+}
+
+} /* Image */
+} /* MediaVision */
diff --git a/mv_image/image/src/mv_image_open.cpp b/mv_image/image/src/mv_image_open.cpp
new file mode 100644
index 00000000..1d351a44
--- /dev/null
+++ b/mv_image/image/src/mv_image_open.cpp
@@ -0,0 +1,784 @@
+/**
+ * Copyright (c) 2015 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 "mv_image_open.h"
+
+#include "mv_private.h"
+#include "mv_common_c.h"
+
+#include "ImageObject.h"
+#include "ImageRecognizer.h"
+#include "ImageTrackingModel.h"
+#include "ImageTracker.h"
+
+#include <opencv/cv.h>
+
+namespace
+{
+
+const MediaVision::Image::FeaturesExtractingParams
+ defaultObjectFeaturesExtractingParams(1.2, 1000);
+
+const MediaVision::Image::FeaturesExtractingParams
+ defaultSceneFeaturesExtractingParams(1.2, 5000);
+
+const MediaVision::Image::RecognitionParams
+ defaultRecognitionParams(15, 0.33, 0.1);
+
+const MediaVision::Image::StabilizationParams
+ defaultStabilizationParams(3, 0.006, 2, 0.001);
+
+const MediaVision::Image::TrackingParams
+ defaultTrackingParams(
+ defaultSceneFeaturesExtractingParams,
+ defaultRecognitionParams,
+ defaultStabilizationParams,
+ 0.0);
+
+void extractTargetFeaturesExtractingParams(
+ mv_engine_config_h engine_cfg,
+ MediaVision::Image::FeaturesExtractingParams& featuresExtractingParams)
+{
+ mv_engine_config_h working_cfg = NULL;
+
+ if (NULL == engine_cfg)
+ {
+ mv_create_engine_config(&working_cfg);
+ }
+ else
+ {
+ working_cfg = engine_cfg;
+ }
+
+ featuresExtractingParams = defaultObjectFeaturesExtractingParams;
+
+ mv_engine_config_get_double_attribute_c(
+ working_cfg,
+ "MV_IMAGE_RECOGNITION_OBJECT_SCALE_FACTOR",
+ &featuresExtractingParams.mScaleFactor);
+
+ mv_engine_config_get_int_attribute_c(
+ working_cfg,
+ "MV_IMAGE_RECOGNITION_OBJECT_MAX_KEYPOINTS_NUM",
+ &featuresExtractingParams.mMaximumFeaturesNumber);
+
+ if (NULL == engine_cfg)
+ {
+ mv_destroy_engine_config(working_cfg);
+ }
+}
+
+void extractSceneFeaturesExtractingParams(
+ mv_engine_config_h engine_cfg,
+ MediaVision::Image::FeaturesExtractingParams& featuresExtractingParams)
+{
+ mv_engine_config_h working_cfg = NULL;
+
+ if (NULL == engine_cfg)
+ {
+ mv_create_engine_config(&working_cfg);
+ }
+ else
+ {
+ working_cfg = engine_cfg;
+ }
+
+ featuresExtractingParams = defaultSceneFeaturesExtractingParams;
+
+ mv_engine_config_get_double_attribute_c(
+ working_cfg,
+ "MV_IMAGE_RECOGNITION_SCENE_SCALE_FACTOR",
+ &featuresExtractingParams.mScaleFactor);
+
+ mv_engine_config_get_int_attribute_c(
+ working_cfg,
+ "MV_IMAGE_RECOGNITION_SCENE_MAX_KEYPOINTS_NUM",
+ &featuresExtractingParams.mMaximumFeaturesNumber);
+
+ if (NULL == engine_cfg)
+ {
+ mv_destroy_engine_config(working_cfg);
+ }
+}
+
+void extractRecognitionParams(
+ mv_engine_config_h engine_cfg,
+ MediaVision::Image::RecognitionParams& recognitionParams)
+{
+ mv_engine_config_h working_cfg = NULL;
+
+ if (NULL == engine_cfg)
+ {
+ mv_create_engine_config(&working_cfg);
+ }
+ else
+ {
+ working_cfg = engine_cfg;
+ }
+
+ recognitionParams = defaultRecognitionParams;
+
+ mv_engine_config_get_int_attribute_c(
+ working_cfg,
+ "MV_IMAGE_RECOGNITION_MIN_MATCH_NUM",
+ &recognitionParams.mMinMatchesNumber);
+
+ mv_engine_config_get_double_attribute_c(
+ working_cfg,
+ "MV_IMAGE_RECOGNITION_REQ_MATCH_PART",
+ &recognitionParams.mRequiredMatchesPart);
+
+ mv_engine_config_get_double_attribute_c(
+ working_cfg,
+ "MV_IMAGE_RECOGNITION_TOLERANT_MATCH_PART_ERR",
+ &recognitionParams.mAllowableMatchesPartError);
+
+ if (NULL == engine_cfg)
+ {
+ mv_destroy_engine_config(working_cfg);
+ }
+}
+
+void extractStabilizationParams(
+ mv_engine_config_h engine_cfg,
+ MediaVision::Image::StabilizationParams& stabilizationParams)
+{
+ mv_engine_config_h working_cfg = NULL;
+
+ if (NULL == engine_cfg)
+ {
+ mv_create_engine_config(&working_cfg);
+ }
+ else
+ {
+ working_cfg = engine_cfg;
+ }
+
+ stabilizationParams = defaultStabilizationParams;
+
+ bool useStabilization = true;
+ mv_engine_config_get_bool_attribute_c(
+ working_cfg,
+ "MV_IMAGE_TRACKING_USE_STABLIZATION",
+ &useStabilization);
+
+ if (!useStabilization)
+ {
+ stabilizationParams.mHistoryAmount = 0;
+ if (NULL == engine_cfg)
+ {
+ mv_destroy_engine_config(working_cfg);
+ }
+ return;
+ }
+
+ mv_engine_config_get_int_attribute_c(
+ working_cfg,
+ "MV_IMAGE_TRACKING_HISTORY_AMOUNT",
+ &stabilizationParams.mHistoryAmount);
+
+ mv_engine_config_get_double_attribute_c(
+ working_cfg,
+ "MV_IMAGE_TRACKING_STABLIZATION_TOLERANT_SHIFT",
+ &stabilizationParams.mAllowableShift);
+
+ mv_engine_config_get_double_attribute_c(
+ working_cfg,
+ "MV_IMAGE_TRACKING_STABLIZATION_SPEED",
+ &stabilizationParams.mStabilizationSpeed);
+
+ mv_engine_config_get_double_attribute_c(
+ working_cfg,
+ "MV_IMAGE_TRACKING_STABLIZATION_ACCELERATION",
+ &stabilizationParams.mStabilizationAcceleration);
+
+ if (NULL == engine_cfg)
+ {
+ mv_destroy_engine_config(working_cfg);
+ }
+}
+
+void extractTrackingParams(
+ mv_engine_config_h engine_cfg,
+ MediaVision::Image::TrackingParams& trackingParams)
+{
+ mv_engine_config_h working_cfg = NULL;
+
+ if (NULL == engine_cfg)
+ {
+ mv_create_engine_config(&working_cfg);
+ }
+ else
+ {
+ working_cfg = engine_cfg;
+ }
+
+ trackingParams = defaultTrackingParams;
+
+ extractSceneFeaturesExtractingParams(
+ working_cfg,
+ trackingParams.mFramesFeaturesExtractingParams);
+
+ extractRecognitionParams(
+ working_cfg,
+ trackingParams.mRecognitionParams);
+
+ extractStabilizationParams(
+ working_cfg,
+ trackingParams.mStabilizationParams);
+
+ mv_engine_config_get_double_attribute_c(
+ working_cfg,
+ "MV_IMAGE_TRACKING_EXPECTED_OFFSET",
+ &trackingParams.mExpectedOffset);
+
+ if (NULL == engine_cfg)
+ {
+ mv_destroy_engine_config(working_cfg);
+ }
+}
+
+int convertSourceMV2GrayCV(mv_source_h mvSource, cv::Mat& cvSource)
+{
+ MEDIA_VISION_INSTANCE_CHECK(mvSource);
+
+ int depth = CV_8U; // Default depth. 1 byte for channel.
+ unsigned int channelsNumber = 0u;
+ unsigned int width = 0u, height = 0u;
+ unsigned int bufferSize = 0u;
+ unsigned char *buffer = NULL;
+
+ mv_colorspace_e colorspace = MEDIA_VISION_COLORSPACE_INVALID;
+
+ MEDIA_VISION_ASSERT(mv_source_get_width(mvSource, &width),
+ "Failed to get the width.");
+ MEDIA_VISION_ASSERT(mv_source_get_height(mvSource, &height),
+ "Failed to get the height.");
+ MEDIA_VISION_ASSERT(mv_source_get_colorspace(mvSource, &colorspace),
+ "Failed to get the colorspace.");
+ MEDIA_VISION_ASSERT(mv_source_get_buffer(mvSource, &buffer, &bufferSize),
+ "Failed to get the buffer size.");
+
+ int conversionType = -1; // Type of conversion from given colorspace to gray
+ switch(colorspace)
+ {
+ case MEDIA_VISION_COLORSPACE_INVALID:
+ LOGE("Error: mv_source has invalid colorspace.");
+ return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+ case MEDIA_VISION_COLORSPACE_Y800:
+ channelsNumber = 1;
+ // Without convertion
+ break;
+ case MEDIA_VISION_COLORSPACE_I420:
+ channelsNumber = 1;
+ height *= 1.5;
+ conversionType = CV_YUV2GRAY_I420;
+ break;
+ case MEDIA_VISION_COLORSPACE_NV12:
+ channelsNumber = 1;
+ height *= 1.5;
+ conversionType = CV_YUV2GRAY_NV12;
+ break;
+ case MEDIA_VISION_COLORSPACE_YV12:
+ channelsNumber = 1;
+ height *= 1.5;
+ conversionType = CV_YUV2GRAY_YV12;
+ break;
+ case MEDIA_VISION_COLORSPACE_NV21:
+ channelsNumber = 1;
+ height *= 1.5;
+ conversionType = CV_YUV2GRAY_NV21;
+ break;
+ case MEDIA_VISION_COLORSPACE_YUYV:
+ channelsNumber = 2;
+ conversionType = CV_YUV2GRAY_YUYV;
+ break;
+ case MEDIA_VISION_COLORSPACE_UYVY:
+ channelsNumber = 2;
+ conversionType = CV_YUV2GRAY_UYVY;
+ break;
+ case MEDIA_VISION_COLORSPACE_422P:
+ channelsNumber = 2;
+ conversionType = CV_YUV2GRAY_Y422;
+ break;
+ case MEDIA_VISION_COLORSPACE_RGB565:
+ channelsNumber = 2;
+ conversionType = CV_BGR5652GRAY;
+ break;
+ case MEDIA_VISION_COLORSPACE_RGB888:
+ channelsNumber = 3;
+ conversionType = CV_RGB2GRAY;
+ break;
+ case MEDIA_VISION_COLORSPACE_RGBA:
+ channelsNumber = 4;
+ conversionType = CV_RGBA2GRAY;
+ break;
+ default:
+ LOGE("Error: mv_source has unsupported colorspace.");
+ return MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT;
+ }
+
+ if (conversionType == -1) // Without conversion
+ {
+ cvSource = cv::Mat(cv::Size(width, height),
+ CV_MAKETYPE(depth, channelsNumber), buffer).clone();
+ }
+ else // Conversion
+ {
+ // Class for representation the given image as cv::Mat before conversion
+ cv::Mat origin(cv::Size(width, height),
+ CV_MAKETYPE(depth, channelsNumber), buffer);
+ cv::cvtColor(origin, cvSource, conversionType);
+ }
+
+ return MEDIA_VISION_ERROR_NONE;
+}
+
+} /* anonymous namespace */
+
+int mv_image_recognize_open(
+ mv_source_h source,
+ const mv_image_object_h *image_objects,
+ int number_of_objects,
+ mv_engine_config_h engine_cfg,
+ mv_image_recognized_cb recognized_cb,
+ void *user_data)
+{
+ MEDIA_VISION_INSTANCE_CHECK(source);
+ MEDIA_VISION_NULL_ARG_CHECK(image_objects);
+ for (int objectNum = 0; objectNum < number_of_objects; ++objectNum)
+ {
+ MEDIA_VISION_INSTANCE_CHECK(image_objects[objectNum]);
+ }
+ MEDIA_VISION_NULL_ARG_CHECK(recognized_cb);
+
+ cv::Mat scene;
+ MEDIA_VISION_ASSERT(
+ convertSourceMV2GrayCV(source, scene),
+ "Failed to convert mv_source.");
+
+ MediaVision::Image::FeaturesExtractingParams featuresExtractingParams;
+ extractSceneFeaturesExtractingParams(engine_cfg, featuresExtractingParams);
+
+ MediaVision::Image::RecognitionParams recognitionParams;
+ extractRecognitionParams(engine_cfg, recognitionParams);
+
+ MediaVision::Image::ImageRecognizer recognizer(scene,
+ featuresExtractingParams);
+
+ mv_quadrangle_s *resultLocations[number_of_objects];
+
+ for (int objectNum = 0; objectNum < number_of_objects; ++objectNum)
+ {
+ std::vector<cv::Point2f> resultContour;
+ bool isRecognized = recognizer.recognize(
+ *((MediaVision::Image::ImageObject*)image_objects[objectNum]),
+ recognitionParams, resultContour);
+ if (isRecognized && (resultContour.size() ==
+ MediaVision::Image::NumberOfQuadrangleCorners))
+ {
+ resultLocations[objectNum] = new mv_quadrangle_s;
+ for (size_t pointNum = 0u;
+ pointNum < MediaVision::Image::NumberOfQuadrangleCorners;
+ ++pointNum)
+ {
+ resultLocations[objectNum]->points[pointNum].x =
+ resultContour[pointNum].x;
+ resultLocations[objectNum]->points[pointNum].y =
+ resultContour[pointNum].y;
+ }
+ }
+ else
+ {
+ resultLocations[objectNum] = NULL;
+ }
+ }
+
+ recognized_cb(
+ source,
+ engine_cfg,
+ image_objects,
+ resultLocations,
+ number_of_objects,
+ user_data);
+
+ for (int objectNum = 0; objectNum < number_of_objects; ++objectNum)
+ {
+ if (resultLocations[objectNum] != NULL)
+ {
+ delete resultLocations[objectNum];
+ resultLocations[objectNum] = NULL;
+ }
+ }
+
+ return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_image_track_open(
+ mv_source_h source,
+ mv_image_tracking_model_h image_tracking_model,
+ mv_engine_config_h engine_cfg,
+ mv_image_tracked_cb tracked_cb,
+ void *user_data)
+{
+ MEDIA_VISION_INSTANCE_CHECK(source);
+ MEDIA_VISION_INSTANCE_CHECK(image_tracking_model);
+ MEDIA_VISION_NULL_ARG_CHECK(tracked_cb);
+
+ if (!((MediaVision::Image::ImageTrackingModel*)image_tracking_model)->isValid())
+ {
+ LOGE("[%s] Image tracking model is invalid.", __FUNCTION__);
+ return MEDIA_VISION_ERROR_INVALID_DATA;
+ }
+
+ MediaVision::Image::TrackingParams trackingParams;
+ extractTrackingParams(engine_cfg, trackingParams);
+
+ cv::Mat frame;
+ MEDIA_VISION_ASSERT(
+ convertSourceMV2GrayCV(source, frame),
+ "Failed to convert mv_source.");
+
+ MediaVision::Image::ImageTracker tracker(trackingParams);
+
+ MediaVision::Image::ImageTrackingModel *trackingModel =
+ (MediaVision::Image::ImageTrackingModel*)image_tracking_model;
+
+ tracker.track(frame, *trackingModel);
+
+ std::vector<cv::Point2f> resultContour = trackingModel->getLastlocation();
+
+ if (trackingModel->isDetected() &&
+ MediaVision::Image::NumberOfQuadrangleCorners == resultContour.size())
+ {
+ mv_quadrangle_s result;
+ for (size_t pointNum = 0u;
+ pointNum < MediaVision::Image::NumberOfQuadrangleCorners;
+ ++pointNum)
+ {
+ result.points[pointNum].x = resultContour[pointNum].x;
+ result.points[pointNum].y = resultContour[pointNum].y;
+ }
+ tracked_cb(source, image_tracking_model, engine_cfg, &result, user_data);
+ }
+ else
+ {
+ tracked_cb(source, image_tracking_model, engine_cfg, NULL, user_data);
+ }
+
+ return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_image_object_create_open(
+ mv_image_object_h *image_object)
+{
+ MEDIA_VISION_NULL_ARG_CHECK(image_object);
+
+ (*image_object) = (mv_image_object_h)new (std::nothrow)MediaVision::Image::ImageObject();
+ if (*image_object == NULL)
+ {
+ return MEDIA_VISION_ERROR_OUT_OF_MEMORY;
+ }
+
+ return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_image_object_destroy_open(
+ mv_image_object_h image_object)
+{
+ MEDIA_VISION_INSTANCE_CHECK(image_object);
+
+ delete (MediaVision::Image::ImageObject*)image_object;
+
+ return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_image_object_fill_open(
+ mv_image_object_h image_object,
+ mv_engine_config_h engine_cfg,
+ mv_source_h source,
+ mv_rectangle_s *location)
+{
+ MEDIA_VISION_INSTANCE_CHECK(image_object);
+ MEDIA_VISION_INSTANCE_CHECK(source);
+
+ cv::Mat image;
+ MEDIA_VISION_ASSERT(
+ convertSourceMV2GrayCV(source, image),
+ "Failed to convert mv_source.");
+
+ MediaVision::Image::FeaturesExtractingParams featuresExtractingParams;
+ extractTargetFeaturesExtractingParams(engine_cfg, featuresExtractingParams);
+
+ if (NULL == location)
+ {
+ ((MediaVision::Image::ImageObject*)image_object)->fill(image,
+ featuresExtractingParams);
+ }
+ else
+ {
+ if (!((MediaVision::Image::ImageObject*)image_object)->fill(image,
+ cv::Rect(location->point.x, location->point.y,
+ location->width, location->height),
+ featuresExtractingParams))
+ {
+ // Wrong ROI (bounding box)
+ LOGE("[%s] Wrong ROI.", __FUNCTION__);
+ return MEDIA_VISION_ERROR_INVALID_DATA;
+ }
+ }
+
+ return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_image_object_get_recognition_rate_open(
+ mv_image_object_h image_object,
+ double *recognition_rate)
+{
+ MEDIA_VISION_INSTANCE_CHECK(image_object);
+ MEDIA_VISION_NULL_ARG_CHECK(recognition_rate);
+
+ (*recognition_rate) =
+ ((MediaVision::Image::ImageObject*)image_object)->getRecognitionRate();
+
+ return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_image_object_set_label_open(
+ mv_image_object_h image_object,
+ int label)
+{
+ MEDIA_VISION_INSTANCE_CHECK(image_object);
+
+ ((MediaVision::Image::ImageObject*)image_object)->setLabel(label);
+
+ return MEDIA_VISION_ERROR_NONE;
+}
+int mv_image_object_get_label_open(
+ mv_image_object_h image_object,
+ int *label)
+{
+ MEDIA_VISION_INSTANCE_CHECK(image_object);
+ MEDIA_VISION_NULL_ARG_CHECK(label);
+
+ if (!((MediaVision::Image::ImageObject*)image_object)->getLabel(*label))
+ {
+ LOGW("[%s] Image object haven't a label.", __FUNCTION__);
+ return MEDIA_VISION_ERROR_NO_DATA;
+ }
+
+ return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_image_object_clone_open(
+ mv_image_object_h src,
+ mv_image_object_h *dst)
+{
+ MEDIA_VISION_INSTANCE_CHECK(src);
+ MEDIA_VISION_NULL_ARG_CHECK(dst);
+
+ (*dst) = (mv_image_object_h)new (std::nothrow)MediaVision::Image::ImageObject();
+ if (*dst == NULL)
+ {
+ return MEDIA_VISION_ERROR_OUT_OF_MEMORY;
+ }
+
+ *(MediaVision::Image::ImageObject*)(*dst) =
+ *(MediaVision::Image::ImageObject*)src;
+
+ return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_image_object_save_open(
+ const char *file_name, mv_image_object_h image_object)
+{
+ MEDIA_VISION_INSTANCE_CHECK(image_object);
+
+ if (file_name == NULL)
+ {
+ LOGE("File name is NULL. The file name has to be specified");
+ return MEDIA_VISION_ERROR_INVALID_PATH;
+ }
+
+ int ret = ((MediaVision::Image::ImageObject*)image_object)->save(file_name);
+ if (ret != MEDIA_VISION_ERROR_NONE)
+ {
+ LOGE("Fail to save image object.");
+ return ret;
+ }
+
+ return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_image_object_load_open(
+ const char *file_name, mv_image_object_h *image_object)
+{
+ MEDIA_VISION_NULL_ARG_CHECK(image_object);
+
+ if (file_name == NULL)
+ {
+ LOGE("File name is NULL. The file name has to be specified");
+ return MEDIA_VISION_ERROR_INVALID_PATH;
+ }
+
+ (*image_object) = (mv_image_object_h)new (std::nothrow)MediaVision::Image::ImageObject();
+ if (*image_object == NULL)
+ {
+ return MEDIA_VISION_ERROR_OUT_OF_MEMORY;
+ }
+
+ int ret = ((MediaVision::Image::ImageObject*)(*image_object))->load(file_name);
+ if (ret != MEDIA_VISION_ERROR_NONE)
+ {
+ LOGE("Fail to save image object.");
+ return ret;
+ }
+
+ return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_image_tracking_model_create_open(
+ mv_image_tracking_model_h *image_tracking_model)
+{
+ MEDIA_VISION_NULL_ARG_CHECK(image_tracking_model);
+
+ (*image_tracking_model) = (mv_image_tracking_model_h)
+ new (std::nothrow)MediaVision::Image::ImageTrackingModel();
+ if (*image_tracking_model == NULL)
+ {
+ return MEDIA_VISION_ERROR_OUT_OF_MEMORY;
+ }
+
+ return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_image_tracking_model_set_target_open(
+ mv_image_object_h image_object,
+ mv_image_tracking_model_h image_tracking_model)
+{
+ MEDIA_VISION_INSTANCE_CHECK(image_tracking_model);
+ MEDIA_VISION_INSTANCE_CHECK(image_object);
+
+ if (((MediaVision::Image::ImageObject*)image_object)->isEmpty())
+ {
+ LOGE("[%s] Target is empty and can't be set as target of tracking"
+ "model.", __FUNCTION__);
+ return MEDIA_VISION_ERROR_INVALID_DATA;
+ }
+
+ ((MediaVision::Image::ImageTrackingModel*)image_tracking_model)->setTarget(
+ *(MediaVision::Image::ImageObject*)image_object);
+
+ return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_image_tracking_model_destroy_open(
+ mv_image_tracking_model_h image_tracking_model)
+{
+ MEDIA_VISION_INSTANCE_CHECK(image_tracking_model);
+
+ delete (MediaVision::Image::ImageTrackingModel*)image_tracking_model;
+
+ return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_image_tracking_model_refresh_open(
+ mv_image_tracking_model_h image_tracking_model,
+ mv_engine_config_h /*engine_cfg*/)
+{
+ MEDIA_VISION_INSTANCE_CHECK(image_tracking_model);
+
+ if (!((MediaVision::Image::ImageTrackingModel*)image_tracking_model)->isValid())
+ {
+ LOGE("[%s] Image tracking model is invalid.", __FUNCTION__);
+ return MEDIA_VISION_ERROR_INVALID_DATA;
+ }
+
+ ((MediaVision::Image::ImageTrackingModel*)image_tracking_model)->refresh();
+
+ return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_image_tracking_model_clone_open(
+ mv_image_tracking_model_h src,
+ mv_image_tracking_model_h *dst)
+{
+ MEDIA_VISION_INSTANCE_CHECK(src);
+ MEDIA_VISION_NULL_ARG_CHECK(dst);
+
+ (*dst) = (mv_image_tracking_model_h)new (std::nothrow)MediaVision::Image::ImageTrackingModel();
+ if (*dst == NULL)
+ {
+ return MEDIA_VISION_ERROR_OUT_OF_MEMORY;
+ }
+
+ *(MediaVision::Image::ImageObject*)(*dst) = *(MediaVision::Image::ImageObject*)src;
+
+ LOGD("Image tracking model has been successfully cloned");
+ return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_image_tracking_model_save_open(
+ const char *file_name, mv_image_tracking_model_h image_tracking_model)
+{
+ MEDIA_VISION_INSTANCE_CHECK(image_tracking_model);
+
+ if (file_name == NULL)
+ {
+ LOGE("File name is NULL. The file name has to be specified");
+ return MEDIA_VISION_ERROR_INVALID_PATH;
+ }
+
+ int ret = ((MediaVision::Image::ImageTrackingModel*)image_tracking_model)->save(file_name);
+ if (ret != MEDIA_VISION_ERROR_NONE)
+ {
+ LOGE("Failed to save image tracking model");
+ return ret;
+ }
+
+ LOGD("Image tracking model has been successfully saved");
+ return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_image_tracking_model_load_open(
+ const char *file_name, mv_image_tracking_model_h *image_tracking_model)
+{
+ MEDIA_VISION_NULL_ARG_CHECK(image_tracking_model);
+
+ if (file_name == NULL)
+ {
+ LOGE("File path is NULL. The file name has to be specified");
+ return MEDIA_VISION_ERROR_INVALID_PATH;
+ }
+
+ (*image_tracking_model) =
+ (mv_image_tracking_model_h) new (std::nothrow)MediaVision::Image::ImageTrackingModel();
+
+ if (*image_tracking_model == NULL)
+ {
+ return MEDIA_VISION_ERROR_OUT_OF_MEMORY;
+ }
+
+ int ret = ((MediaVision::Image::ImageTrackingModel*)(*image_tracking_model))->load(file_name);
+ if (ret != MEDIA_VISION_ERROR_NONE)
+ {
+ LOGE("Failed to load image tracking model");
+ return ret;
+ }
+
+ LOGD("Image tracking model has been successfully loaded");
+ return MEDIA_VISION_ERROR_NONE;
+}
diff --git a/mv_image/image_lic/CMakeLists.txt b/mv_image/image_lic/CMakeLists.txt
new file mode 100644
index 00000000..b38e47b8
--- /dev/null
+++ b/mv_image/image_lic/CMakeLists.txt
@@ -0,0 +1,25 @@
+project(${MV_IMAGE_LIB_NAME})
+cmake_minimum_required(VERSION 2.6)
+
+set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_DEBUG _DEBUG)
+
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${LIB_INSTALL_DIR})
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${LIB_INSTALL_DIR})
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
+
+include_directories("${INC_DIR}")
+include_directories("${PROJECT_SOURCE_DIR}/include")
+include_directories("${PROJECT_SOURCE_DIR}/src")
+
+file(GLOB MV_IMAGE_INC_LIST "${PROJECT_SOURCE_DIR}/include/*.h")
+file(GLOB MV_IMAGE_SRC_LIST "${PROJECT_SOURCE_DIR}/src/*.c")
+
+if(FORCED_STATIC_BUILD)
+ add_library(${PROJECT_NAME} STATIC ${MV_IMAGE_INC_LIST} ${MV_IMAGE_SRC_LIST})
+else()
+ add_library(${PROJECT_NAME} SHARED ${MV_IMAGE_INC_LIST} ${MV_IMAGE_SRC_LIST})
+endif()
+
+target_link_libraries(${PROJECT_NAME} ${MV_COMMON_LIB_NAME})
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR})
diff --git a/mv_image/image_lic/include/mv_image_lic.h b/mv_image/image_lic/include/mv_image_lic.h
new file mode 100644
index 00000000..29e1c1dc
--- /dev/null
+++ b/mv_image/image_lic/include/mv_image_lic.h
@@ -0,0 +1,564 @@
+/**
+ * Copyright (c) 2015 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 __TIZEN_MEDIAVISION_IMAGE_LIC_H__
+#define __TIZEN_MEDIAVISION_IMAGE_LIC_H__
+
+#include "mv_image.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @file mv_image_lic.h
+ * @brief This file contains the Media Vision Image API for the licensed module.
+ * Working with images (like planar objects): recognition and tracking.
+ */
+
+/****************************/
+/* Image object recognition */
+/****************************/
+
+/**
+ * @brief Recognizes the given image objects on the source image.
+ * @details Use this function to launch image recognition algorithm configured
+ * by @a engine_conf configuration.
+ *
+ * @since_tizen 3.0
+ * @param [in] source The handle to the source image on which image
+ * objects will be recognized
+ * @param [in] image_objects The set of handles to the image objects which
+ * will be processed as targets of recognition
+ * @param [in] number_of_objects The number of image objects
+ * @param [in] engine_cfg The handle to the configuration of engine
+ * which will be used for recognition. If NULL,
+ * then default settings will be used.
+ * @param [in] recognized_cb The callback which will be called in order to
+ * process recognition result
+ * @param [in] user_data The user data to be passed to the
+ * @a recognized_cb
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT Source colorspace
+ * isn't supported
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create a set of image objects using @ref mv_image_object_create_lic()
+ * for each of them and construct (fill / load / clone) them on images that
+ * will be recognized
+ * @pre Create a source handle by calling @ref mv_create_source() and fill
+ * by the image for which recognition will be performed
+ * @post @a mv_image_recognized_cb will be called to process recognition result
+ * @post Release source image by using @ref mv_destroy_source()
+ * @post Release image objects by using @ref mv_image_object_destroy_lic() for
+ * each handle from @a image_objects set
+ *
+ * @see mv_image_recognized_cb
+ * @see mv_source_h
+ * @see mv_create_source()
+ * @see mv_destroy_source()
+ * @see mv_image_object_h
+ * @see mv_image_object_create_lic()
+ * @see mv_image_object_destroy_lic()
+ * @see mv_engine_config_h
+ */
+int mv_image_recognize_lic(
+ mv_source_h source,
+ const mv_image_object_h *image_objects,
+ int number_of_objects,
+ mv_engine_config_h engine_cfg,
+ mv_image_recognized_cb recognized_cb,
+ void *user_data);
+
+/*************************/
+/* Image object tracking */
+/*************************/
+
+/**
+ * @brief Tracks the given image tracking model on the current frame
+ * @details Image tracking on a sequence of frames assumes calling this
+ * function for each frame in the correct order.
+ * @a tracked_cb will be called for result processing.
+ *
+ * @since_tizen 3.0
+ * @remarks Tracking algorithm is usually using for recognition of image object
+ * on the sequence of images that are organized by time. For example,
+ * it may be the sequence of frames from a video stream.
+ * @remarks If object is lost during the tracking, system tries to find it
+ * further for the following frames. Therefore, tracking will be
+ * recovered when object appears again.
+ * @remarks Previous calls of @ref mv_image_track_lic() for this
+ * @a image_tracking_model will affect on current call
+ * @param [in] source The handle to the current image of
+ * sequence where image tracking model
+ * will be tracked
+ * @param [in,out] image_tracking_model The handle to the image tracking model
+ * which processed as target of tracking
+ * @param [in] engine_cfg The handle to the configuration of
+ * engine which will be used for tracking.
+ * If NULL, then default settings will be
+ * used.
+ * @param [in] tracked_cb The callback which will receive
+ * tracking results
+ * @param [in] user_data The user data to be passed to the
+ * @a tracked_cb
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT Source colorspace
+ * isn't supported
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create image tracking model by calling
+ * @ref mv_image_tracking_model_create_lic() and set target by calling
+ * @ref mv_image_tracking_model_set_target_lic()
+ * @pre Create a source images by calling @ref mv_create_source() for each of
+ * them and construct them based on sequence of images for which will be
+ * held image tracking
+ * @post @a tracked_cb will be called to process tracking result
+ * @post Release image tracking model by using
+ * @ref mv_image_tracking_model_destroy_lic()
+ *
+ * @see mv_image_tracked_cb
+ * @see mv_source_h
+ * @see image_tracking_model_h
+ * @see mv_image_tracking_model_create_lic()
+ * @see mv_image_tracking_model_set_target_lic()
+ * @see mv_image_tracking_model_destroy_lic()
+ */
+int mv_image_track_lic(
+ mv_source_h source,
+ mv_image_tracking_model_h image_tracking_model,
+ mv_engine_config_h engine_cfg,
+ mv_image_tracked_cb tracked_cb,
+ void *user_data);
+
+/**************************/
+/* Image object behaviour */
+/**************************/
+
+/**
+ * @brief Creates an image object.
+ *
+ * @since_tizen 3.0
+ * @param [out] image_object A new handle to the image object
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Release image object by using mv_image_object_destroy_lic()
+ *
+ * @see mv_image_object_destroy_lic()
+ */
+int mv_image_object_create_lic(
+ mv_image_object_h *image_object);
+
+/**
+ * @brief Destroys the image object.
+ *
+ * @since_tizen 3.0
+ * @param [in] image_object The handle to the image object to be destroyed
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @see mv_image_object_create_lic()
+ */
+int mv_image_object_destroy_lic(
+ mv_image_object_h image_object);
+
+/**
+ * @brief Fills the image object.
+ * @details Extracts data from @a source image which will be needed for
+ * recognition of depicted object in @a location.
+ *
+ * @since_tizen 3.0
+ * @remarks After filling the image object it can be evaluated by
+ * @ref mv_image_object_get_recognition_rate_lic(). If recognition rate
+ * is too low, try to use another image of object or change
+ * configuration parameters (see @ref mv_engine_config_h) and construct
+ * the image object again.
+ * @param [in,out] image_object The handle to the image object which will be
+ * filled and can be recognized in future
+ * @param [in] engine_cfg The handle to the configuration of engine
+ * which will be used for extract recognition
+ * data from @a source. If NULL, then default
+ * settings will be used.
+ * @param [in] source The source image where image object is depicted
+ * @param [in] location The pointer to location of the image object
+ * on the source image, or NULL if the object is
+ * shown in full
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT Source colorspace
+ * isn't supported
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create image object by using @ref mv_image_object_create_lic()
+ * @post Release image object by using @ref mv_image_object_destroy_lic()
+ *
+ * @see mv_image_object_h
+ * @see mv_image_object_create_lic()
+ * @see mv_image_object_get_recognition_rate_lic()
+ * @see mv_image_recognize_lic()
+ * @see mv_image_object_destroy_lic()
+ * @see mv_engine_config_h
+ */
+int mv_image_object_fill_lic(
+ mv_image_object_h image_object,
+ mv_engine_config_h engine_cfg,
+ mv_source_h source,
+ mv_rectangle_s *location);
+
+/**
+ * @brief Gets a value that determines how well an image object can be recognized.
+ * @details Recognition rate determines how well an image object can be
+ * recognized. This value can be from 0 to 1. If the recognition rate
+ * is 0 object can not be recognized and the bigger it is the more
+ * likely to recognize the object.
+ *
+ * @since_tizen 3.0
+ * @remarks If recognition rate is too low, try to use another image of object
+ * or change some configuration parameters (see @ref mv_engine_config_h)
+ * and fill the image object again
+ * (see @ref mv_image_object_fill_lic()).
+ * @param [in] image_object The handle to the image object which will be
+ * evaluated by this function
+ * @param [out] recognition_rate A value that determines how well an image
+ * object can be recognized, if 0 then object
+ * can not be recognized
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create image object by using @ref mv_image_object_create_lic()
+ * @post Release image object by using @ref mv_image_object_destroy_lic()
+ *
+ * @see mv_image_object_h
+ * @see mv_image_object_create_lic()
+ * @see mv_image_object_fill_lic()
+ * @see mv_image_object_destroy_lic()
+ * @see mv_engine_config_h
+ */
+int mv_image_object_get_recognition_rate_lic(
+ mv_image_object_h image_object,
+ double *recognition_rate);
+
+/**
+ * @brief Sets a label for the image object.
+ *
+ * @since_tizen 3.0
+ * @param [in] image_object The handle to the image object for which the label
+ * will be assigned
+ * @param [in] label The label which will be assigned to the image
+ * object
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create image object by using @ref mv_image_object_create_lic()
+ * @post Label could be received by using
+ * @ref mv_image_object_get_label_lic()
+ * @post Release image object by using @ref mv_image_object_destroy_lic()
+ *
+ * @see mv_image_object_get_label_lic()
+ * @see mv_image_object_h
+ * @see mv_image_object_create_lic()
+ * @see mv_image_object_destroy_lic()
+ */
+int mv_image_object_set_label_lic(
+ mv_image_object_h image_object,
+ int label);
+
+/**
+ * @brief Gets a label of image object.
+ *
+ * @since_tizen 3.0
+ * @remarks If @a image_object have not a label, this function return
+ * MEDIA_VISION_ERROR_NO_DATA value.
+ * @param [in] image_object The handle to the image object from which a
+ * label will be received
+ * @param [out] label The label of image object
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NO_DATA Image object hasn't label
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create image object by using @ref mv_image_object_create_lic()
+ * @pre Set label for the image object by using
+ * @ref mv_image_object_set_label_lic()
+ * @post Release image object by using @ref mv_image_object_destroy_lic()
+ *
+ * @see mv_image_object_set_label_lic()
+ * @see mv_image_object_h
+ * @see mv_image_object_create_lic()
+ * @see mv_image_object_destroy_lic()
+ */
+int mv_image_object_get_label_lic(
+ mv_image_object_h image_object,
+ int *label);
+
+/**
+ * @brief Clones the image object.
+ *
+ * @since_tizen 3.0
+ * @param [in] src The handle to the source image object
+ * @param [out] dst The handle to the destination image object
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create image object handles by calling mv_image_object_create_lic()
+ *
+ * @see mv_image_object_create_lic()
+ * @see mv_image_object_destroy_lic()
+ */
+int mv_image_object_clone_lic(
+ mv_image_object_h src,
+ mv_image_object_h *dst);
+
+/**
+ * @brief Saves the image object.
+ *
+ * @since_tizen 3.0
+ * @remarks @a image_object is saved to the application's data directory.
+ * @param [in] file_name Name of the file to save the image object
+ * @param [in] image_object The handle to the image object which will be saved
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @see mv_image_object_create_lic()
+ * @see mv_image_object_load_lic()
+ * @see mv_image_object_destroy_lic()
+ */
+int mv_image_object_save_lic(
+ const char *file_name, mv_image_object_h image_object);
+
+/**
+ * @brief Loads an image object from the file.
+ *
+ * @since_tizen 3.0
+ * @remarks @a image_object is loaded from the application's data directory.
+ * @a image_object must be destroyed using
+ * @ref mv_image_object_destroy().
+ * @param [in] file_name Name of file to load the image object
+ * @param [out] image_object The handle to the image object which will be
+ * filled
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Image object can be preliminary saved with mv_image_object_save()
+ * function
+ *
+ * @see mv_image_object_save_lic()
+ * @see mv_image_object_destroy_lic()
+ */
+int mv_image_object_load_lic(
+ const char *file_name, mv_image_object_h image_object);
+
+/**********************************/
+/* Image tracking model behaviour */
+/**********************************/
+
+/**
+ * @brief Creates an image tracking model.
+ *
+ * @since_tizen 3.0
+ * @param [out] image_tracking_model A new handle to the image tracking model
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Release image tracking model by using mv_image_tracking_model_destroy_lic()
+ *
+ * @see mv_image_tracking_model_destroy_lic()
+ */
+int mv_image_tracking_model_create_lic(
+ mv_image_tracking_model_h *image_tracking_model);
+
+/**
+ * @brief Sets target of image tracking model.
+ * @details Sets image object which will be tracked by using tracking
+ * functionality with @a image_tracking_model.
+ *
+ * @since_tizen 3.0
+ * @param [in] image_object Image object which will be set
+ * as target for tracking
+ * @param [in] image_tracking_model Handle to the image tracking model
+ * for which will be set a new target
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create image tracking model by calling
+ * @ref mv_image_tracking_model_create_lic()
+ * @pre Create an image object using @ref mv_image_object_create_lic() and
+ * construct (fill / load / clone) it on image that will be tracking
+ * @post Release image object by using @ref mv_image_object_destroy_lic()
+ * @post Release image tracking model by using
+ * @ref mv_image_tracking_model_destroy_lic()
+ *
+ * @see mv_image_object_h
+ * @see mv_image_tracking_model_h
+ * @see mv_image_object_create_lic()
+ * @see mv_image_object_destroy_lic()
+ * @see mv_image_tracking_model_create_lic()
+ * @see mv_image_track_lic()
+ * @see mv_image_tracking_model_destroy_lic()
+ */
+int mv_image_tracking_model_set_target_lic(
+ mv_image_object_h image_object,
+ mv_image_tracking_model_h image_tracking_model);
+
+/**
+ * @brief Destroys the image tracking model.
+ *
+ * @since_tizen 3.0
+ * @param [in] image_tracking_model The handle to the image tracking model
+ * to be destroyed
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create image tracking model by using mv_image_tracking_model_create()
+ *
+ * @see mv_image_tracking_model_create_lic()
+ */
+int mv_image_tracking_model_destroy_lic(
+ mv_image_tracking_model_h image_tracking_model);
+
+/**
+ * @brief Refreshes the state of image tracking model.
+ * @details Clears moving history and change state to undetected. This function
+ * is usually called each time before tracking is started for the new
+ * sequence of sources which is not the direct continuation of the
+ * sequence for which tracking has been performed before. Tracking
+ * algorithm will try to find image by itself.
+ *
+ * @since_tizen 3.0
+ * @param [in] image_tracking_model The handle to the image tracking model
+ * which will be refreshed
+ * @param [in] engine_cfg The handle to the configuration of
+ * engine which will be used. If NULL,
+ * then default settings will be used.
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create image tracking model by calling
+ * @ref mv_image_tracking_model_create_lic()
+ * @post Release image tracking model by using
+ * @ref mv_image_tracking_model_destroy_lic()
+ *
+ * @see mv_image_tracking_model_h
+ * @see mv_image_tracking_model_create_lic()
+ * @see mv_image_track_lic()
+ * @see mv_image_tracking_model_destroy_lic()
+ */
+int mv_image_tracking_model_refresh_lic(
+ mv_image_tracking_model_h image_tracking_model,
+ mv_engine_config_h engine_cfg);
+
+/**
+ * @brief Clones the image tracking model.
+ *
+ * @since_tizen 3.0
+ * @param [in] src The handle to the source image tracking model
+ * @param [out] dst The handle to the destination image tracking model
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @see mv_image_tracking_model_create_lic()
+ * @see mv_image_tracking_model_destroy_lic()
+ */
+int mv_image_tracking_model_clone_lic(
+ mv_image_tracking_model_h src,
+ mv_image_tracking_model_h *dst);
+
+/**
+ * @brief Saves the image tracking model.
+ *
+ * @since_tizen 3.0
+ * @remarks @a image_tracking_model is saved to the application's data directory.
+ * @param [in] file_name Name of file to save the model
+ * @param [in] image_tracking_model The handle to the image tracking model
+ * to be saved
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_PERMISSION_DENIED Not permitted
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Create image tracking model handle by calling
+ * mv_image_tracking_model_create()
+ * @post Saved model can be loaded later by calling
+ * mv_image_tracking_model_load() function
+
+ * @see mv_image_tracking_model_create_lic()
+ * @see mv_image_tracking_model_load_lic()
+ * @see mv_image_tracking_model_destroy_lic()
+ */
+int mv_image_tracking_model_save_lic(
+ const char *file_name, mv_image_tracking_model_h image_tracking_model);
+
+/**
+ * @brief Loads an image tracking model from the file.
+ *
+ * @since_tizen 3.0
+ * @remarks @a image_tracking_model is loaded from the application's data directory.
+ * @a image_tracking_model must be destroyed using
+ * @ref mv_image_tracking_model_destroy.
+ * @param [in] file_name Name of file to load model
+ * @param [out] image_tracking_model The handle to the image tracking
+ * model to be filled
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Image tracking model handle can be preliminary saved with
+ * mv_image_tracking_model_save() function
+ *
+ * @see mv_image_tracking_model_save_lic()
+ * @see mv_image_tracking_model_destroy_lic()
+ */
+int mv_image_tracking_model_load_lic(
+ const char *file_name, mv_image_tracking_model_h *image_tracking_model);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __TIZEN_MEDIAVISION_IMAGE_LIC_H__ */
diff --git a/mv_image/image_lic/src/mv_image_lic.c b/mv_image/image_lic/src/mv_image_lic.c
new file mode 100644
index 00000000..356e563c
--- /dev/null
+++ b/mv_image/image_lic/src/mv_image_lic.c
@@ -0,0 +1,150 @@
+/**
+ * Copyright (c) 2015 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 "mv_image_lic.h"
+
+int mv_image_recognize_lic(
+ mv_source_h source,
+ const mv_image_object_h *image_objects,
+ int number_of_objects,
+ mv_engine_config_h engine_cfg,
+ mv_image_recognized_cb recognized_cb,
+ void *user_data)
+{
+ return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int mv_image_track_lic(
+ mv_source_h source,
+ mv_image_tracking_model_h image_tracking_model,
+ mv_engine_config_h engine_cfg,
+ mv_image_tracked_cb tracked_cb,
+ void *user_data)
+{
+ return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int mv_image_object_create_lic(
+ mv_image_object_h *image_object)
+
+{
+ return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+
+int mv_image_object_destroy_lic(
+ mv_image_object_h image_object)
+{
+ return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int mv_image_object_fill_lic(
+ mv_image_object_h image_object,
+ mv_engine_config_h engine_cfg,
+ mv_source_h source,
+ mv_rectangle_s *location)
+{
+ return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int mv_image_object_get_recognition_rate_lic(
+ mv_image_object_h image_object,
+ double *recognition_rate)
+{
+ return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int mv_image_object_set_label_lic(
+ mv_image_object_h image_object,
+ int label)
+{
+ return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int mv_image_object_get_label_lic(
+ mv_image_object_h image_object,
+ int *label)
+{
+ return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int mv_image_object_clone_lic(
+ mv_image_object_h src,
+ mv_image_object_h *dst)
+{
+ return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int mv_image_object_save_lic(
+ mv_image_object_h image_object,
+ const char *file_name)
+{
+ return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int mv_image_object_load_lic(
+ mv_image_object_h image_object,
+ const char *file_name)
+{
+ return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int mv_image_tracking_model_create_lic(
+ mv_image_tracking_model_h *image_tracking_model)
+{
+ return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int mv_image_tracking_model_set_target_lic(
+ mv_image_object_h image_object,
+ mv_image_tracking_model_h image_tracking_model)
+{
+ return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int mv_image_tracking_model_destroy_lic(
+ mv_image_tracking_model_h image_tracking_model)
+{
+ return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int mv_image_tracking_model_refresh_lic(
+ mv_image_tracking_model_h image_tracking_model,
+ mv_engine_config_h engine_cfg)
+{
+ return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int mv_image_tracking_model_clone_lic(
+ mv_image_tracking_model_h src,
+ mv_image_tracking_model_h *dst)
+{
+ return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int mv_image_tracking_model_save_lic(
+ mv_image_tracking_model_h image_tracking_model,
+ const char *file_name)
+{
+ return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}
+
+int mv_image_tracking_model_load_lic(
+ mv_image_tracking_model_h image_tracking_model,
+ const char *file_name)
+{
+ return MEDIA_VISION_ERROR_NOT_SUPPORTED;
+}