The Flip component will take image data received at its InPort, copy it into an image buffer, and use the cvFlip() function from OpenCV to transform it. The transformed data will be transmitted over the component's OutPort.
The process flow of onActivated(), onExecute() and onDeactivated() is illustrated in Figure 19.
The processing performed by onExecute() is illustrated in Figure 20.
Copy the user_config.vsprops file given below into the Flip component's folder, or save the downloadable version into the component's folder.
※ The user_config.vsprops file that already exists in the Flip folder can be overwritten.
<?xml version="1.0" encoding="shift_jis"?> <VisualStudioPropertySheet ProjectType="Visual C++" Version="8.00" Name="OpenCV" > <Tool Name="VCCLCompilerTool" AdditionalIncludeDirectories="$(cv_includes)" /> <Tool Name="VCLinkerTool" AdditionalLibraryDirectories="$(cv_libdir)" /> <UserMacro Name="user_lib" Value="$(cv_lib)" /> <UserMacro Name="user_libd" Value="$(cv_libd)" /> <UserMacro Name="cv_root" Value="C:\Program Files\OpenCV" /> <UserMacro Name="cv_includes" Value=""$(cv_root)\cv\include";"$(cv_root)\cvaux\include";"$(cv_root)\cxcore\include";"$(cv_root)\otherlibs\highgui";"$(cv_root)\otherlibs\cvcam\include"" /> <UserMacro Name="cv_libdir" Value=""$(cv_root)\lib"" /> <UserMacro Name="cv_bin" Value="$(cv_root)\bin" /> <UserMacro Name="cv_lib" Value="cv.lib cvcam.lib highgui.lib cxcore.lib" /> <UserMacro Name="cv_libd" Value="cv.lib cvcam.lib highgui.lib cxcore.lib" /> </VisualStudioPropertySheet>
Upon executing copyprops.bat, the rtm_config.vsprops file will be copied to the component folder. The rtm_config.vsprops file contains settings such as the include path and extra link libraries necessary to compile an RT-Component using Visual C++.
#include<cv.h> #include<cxcore.h> #include<highgui.h>
/*** * * The activated action (Active state entry action) * former rtc_active_entry() * * @param ec_id target ExecutionContext Id * * @return RTC::ReturnCode_t * * */ virtual RTC::ReturnCode_t onActivated(RTC::UniqueId ec_id); /*** * * The deactivated action (Active state exit action) * former rtc_active_exit() * * @param ec_id target ExecutionContext Id * * @return RTC::ReturnCode_t * * */ virtual RTC::ReturnCode_t onDeactivated(RTC::UniqueId ec_id); /*** * * The execution action that is invoked periodically * former rtc_active_do() * * @param ec_id target ExecutionContext Id * * @return RTC::ReturnCode_t * * */ virtual RTC::ReturnCode_t onExecute(RTC::UniqueId ec_id);
IplImage* m_image_buff; IplImage* m_flip_image_buff;
Implement onActivated(), onDeactivated() and onExecute() as below.
RTC::ReturnCode_t Flip::onActivated(RTC::UniqueId ec_id) { // Image memory store allocation m_image_buff = cvCreateImage(cvSize(m_img_width, m_img_height), IPL_DEPTH_8U, 3); m_flip_image_buff = cvCreateImage(cvSize(m_img_width, m_img_height), IPL_DEPTH_8U, 3); return RTC::RTC_OK; } RTC::ReturnCode_t Flip::onDeactivated(RTC::UniqueId ec_id) { // Image memory store deallocation cvReleaseImage(&m_image_buff); cvReleaseImage(&m_flip_image_buff); return RTC::RTC_OK; } RTC::ReturnCode_t Flip::onExecute(RTC::UniqueId ec_id) { // Check for new data if (m_image_origIn.isNew()) { // Read data from the InPort m_image_origIn.read(); // Copy the image data from the InPort to IplImage.imageData memcpy(m_image_buff->imageData,(void *)&(m_image_orig.data[0]),m_image_orig.data.length()); // Flip the image data. m_flip_mode 0: flip on X, 1: flip on Y, -1: flip on both cvFlip(m_image_buff, m_flip_image_buff, m_flip_mode); // Get the image data size int len = m_flip_image_buff->nChannels * m_flip_image_buff->width * m_flip_image_buff->height; m_image_flip.data.length(len); // Copy the flipped image data to the OutPort memcpy((void *)&(m_image_flip.data[0]),m_flip_image_buff->imageData,len); // Output the image data m_image_flipOut.write(); } return RTC::RTC_OK; }
Build the component as in Figure 21.
For testing, the Flip component will be connected to the USBCameraAcquireComp and USBCameraMonitorComp sample components supplied with OpenRTM-aist.
The omniORB name service must be started. From the Start menu, go to All Programs > OpenRTM-aist > C++ > examples > Start Naming Service.
The rtc.conf file is used to tell an RT-Component such parameters as the address of the name server, the format to use when registering with the name server, etc. Copy the following lines into a file called "rtc.conf" and place that file in Flip\FlipComp\Debug or Flip\FlipComp\Release.
corba.nameservers: localhost naming.formats: %n.rtc
In the same folder that the rtc.conf file was placed, execute FlipComp.exe.
The USBCameraAcquire component provides image data captured from a USB camera over its OutPort. The USBCameraMonitor component displays image data received over its InPort. Start them by selecting the following options from the Start menu:
Start > All Programs > OpenRTM-aist > C++ > examples > USBCameraAcquireComp / USBCameraMonitorCpomp
Using RTSystemEditor, connect the three components as in Figure 22.
The Flip component's configuration parameters can be changed as in Figure 23. For example, when using the Elecom UCAM-DLM 130HWH USB camera, set image_height and image_width as below.
image_height : 480 image_width : 640
Do the same for the USBCameraMonitor component.
Click the "All" icon in the toolbar for RTSystemEditor. All the components will be activated. If all components started succesfully, RTSystemEditor should resemble Figure 24.
Try changing the Flip component's "flip_mode" configuration parameter to different values of -1, 0 and 1. The displayed image should change accordingly.
// -*- C++ -*- /*! * @file Flip.cpp * @brief Flip image component * @date $Date$ * * $Id$ */ #include "Flip.h" // Module specification static const char* flip_spec[] = { "implementation_id", "Flip", "type_name", "Flip", "description", "Flip image component", "version", "1.0.0", "vendor", "AIST", "category", "Category", "activity_type", "PERIODIC", "kind", "DataFlowComponent", "max_instance", "1", "language", "C++", "lang_type", "compile", "exec_cxt.periodic.rate", "1.0", // Configuration variables "conf.default.flip_mode", "1", "conf.default.image_height", "240", "conf.default.image_width", "320", "" }; /*! * @brief constructor * @param manager Maneger Object */ Flip::Flip(RTC::Manager* manager) : RTC::DataFlowComponentBase(manager), m_image_origIn("original_image", m_image_orig), m_image_flipOut("fliped_image", m_image_flip), dummy(0), m_image_buff(0), m_flip_image_buff(0) { // Registration: InPort/OutPort/Service // Set InPort buffers registerInPort("original_image", m_image_origIn); // Set OutPort buffer registerOutPort("fliped_image", m_image_flipOut); } /*! * @brief destructor */ Flip::~Flip() { } RTC::ReturnCode_t Flip::onInitialize() { // Bind variables and configuration variable bindParameter("flip_mode", m_flip_mode, "1"); bindParameter("image_height", m_img_height, "240"); bindParameter("image_width", m_img_width, "320"); return RTC::RTC_OK; } RTC::ReturnCode_t Flip::onActivated(RTC::UniqueId ec_id) { // Image memory store allocation m_image_buff = cvCreateImage(cvSize(m_img_width, m_img_height), IPL_DEPTH_8U, 3); m_flip_image_buff = cvCreateImage(cvSize(m_img_width, m_img_height), IPL_DEPTH_8U, 3); return RTC::RTC_OK; } RTC::ReturnCode_t Flip::onDeactivated(RTC::UniqueId ec_id) { // Image memory store deallocation cvReleaseImage(&m_image_buff); cvReleaseImage(&m_flip_image_buff); return RTC::RTC_OK; } RTC::ReturnCode_t Flip::onExecute(RTC::UniqueId ec_id) { // Check for new data if (m_image_origIn.isNew()) { // Read data from the InPort m_image_origIn.read(); // Copy the image data from the InPort to IplImage.imageData memcpy(m_image_buff->imageData,(void *)&(m_image_orig.data[0]),m_image_orig.data.length()); // Flip the image data. m_flip_mode 0: flip on X, 1: flip on Y, -1: flip on both cvFlip(m_image_buff, m_flip_image_buff, m_flip_mode); // Get the image data size int len = m_flip_image_buff->nChannels * m_flip_image_buff->width * m_flip_image_buff->height; m_image_flip.data.length(len); // Copy the flipped image data to the OutPort memcpy((void *)&(m_image_flip.data[0]),m_flip_image_buff->imageData,len); // Output the image data m_image_flipOut.write(); } return RTC::RTC_OK; } extern "C" { void FlipInit(RTC::Manager* manager) { RTC::Properties profile(flip_spec); manager->registerFactory(profile, RTC::Create<Flip>, RTC::Delete<Flip>); } };
// -*- C++ -*- /*! * @file Flip.h * @brief Flip image component * @date $Date$ * * $Id$ */ #ifndef FLIP_H #define FLIP_H #include <rtm/Manager.h> #include <rtm/DataFlowComponentBase.h> #include <rtm/CorbaPort.h> #include <rtm/DataInPort.h> #include <rtm/DataOutPort.h> #include <rtm/idl/BasicDataTypeSkel.h> // (1) Include the OpenCV headers #include<cv.h> #include<cxcore.h> #include<highgui.h> using namespace RTC; /*! * @class Flip * @brief Flip image component * */ class Flip : public RTC::DataFlowComponentBase { public: /*! * @brief constructor * @param manager Maneger Object */ Flip(RTC::Manager* manager); /*! * @brief destructor */ ~Flip(); /*! * * The initialize action (on CREATED->ALIVE transition) * formaer rtc_init_entry() * * @return RTC::ReturnCode_t * * */ virtual RTC::ReturnCode_t onInitialize(); /*** * * The activated action (Active state entry action) * former rtc_active_entry() * * @param ec_id target ExecutionContext Id * * @return RTC::ReturnCode_t * * */ virtual RTC::ReturnCode_t onActivated(RTC::UniqueId ec_id); /*** * * The deactivated action (Active state exit action) * former rtc_active_exit() * * @param ec_id target ExecutionContext Id * * @return RTC::ReturnCode_t * * */ virtual RTC::ReturnCode_t onDeactivated(RTC::UniqueId ec_id); /*** * * The execution action that is invoked periodically * former rtc_active_do() * * @param ec_id target ExecutionContext Id * * @return RTC::ReturnCode_t * * */ virtual RTC::ReturnCode_t onExecute(RTC::UniqueId ec_id); protected: // Configuration variable declaration /*! * flip_mode = 0: flipping around x-axis * flip_mode > 1: flipping around y-axis * flip_mode < 0: flipping around both axises * - Name: flip_mode flip_mode * - DefaultValue: 1 */ int m_flip_mode; /*! * * - Name: m_img_height * - DefaultValue: 240 * - Image height */ int m_img_height; /*! * * - Name: m_img_width * - DefaultValue: 320 * - Image width */ int m_img_width; // DataInPort declaration TimedOctetSeq m_image_orig; InPort<TimedOctetSeq> m_image_origIn; // DataOutPort declaration TimedOctetSeq m_image_flip; OutPort<TimedOctetSeq> m_image_flipOut; private: int dummy; IplImage* m_image_buff; IplImage* m_flip_image_buff; }; extern "C" { void FlipInit(RTC::Manager* manager); }; #endif // FLIP_H
A prebuilt package of the component can be downloaded from here. Remove the underscore from the name and decompress the file.