How to run OpenACC + OpenCV with PGI in Windows? - opencv

I tried to run the code below:
#include <chrono>
#include <omp.h>
#include <vector>
#include <iostream>
#include <algorithm>
#include <string>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
using namespace std;
int main()
{
std::string imgstr = "input.bmp";
cv::Mat imgmat = cv::imread(imgstr, cv::IMREAD_GRAYSCALE);
imgmat.convertTo(imgmat, CV_64FC1, 1.0 / 255.0);
double st = omp_get_wtime();
int i, j;
double res = 0.0;
#pragma acc parallel loop
for (i =0; i <= 10; i++) {
for (j =0; j <=10; j++) {
res =res+ imgmat.at<double>(i, j);
}
}
double runtime = omp_get_wtime() - st;
printf("\n total: %f s\n", runtime);
}
with pgcc -fast -ta=nvidia,managed -Minfo=accel -o runEx runEx.c -lopencv_legacy -lopencv_highgui -lopencv_core && ./runEx in PGI, but I get an error saying
can't find include file opencv2/opencv.hpp
However, the code above compiles and runs successfully in Visual Studio without using OpenACC
can anyone help?

Most likely you need to include the path to header files using the "-I/path/to/openvc/include" flag on the command line. You'll also want to include the library path (via the "-L/path/to/opencv/lib") so it can find the libraries.
Though given "pgcc" is a C compiler, you'll have additional issues given you're using C++ header files and C++ constructs in your code. Current PGI releases do not support C++ on Windows.

Related

how to remove floor surface in the pointcloud2 data with the pcl_ros

first, thanks for reading.
now i am trying to do remove floor in the point cloud data,
this is a code that i wrote to remove the floor point cloud.
#include <iostream>
#include <cmath>
#include <vector>
#include <ros/ros.h>
#include <sensor_msgs/PointCloud2.h>
#include <pcl_ros/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl_conversions/pcl_conversions.h>
#include <velodyne_pointcloud/point_types.h>
#include <pcl/common/common.h>
#include <pcl/common/centroid.h>
#include <pcl/common/transforms.h>
#include <pcl/console/parse.h>
#include <set>
#include <pcl/io/pcd_io.h>
#include <boost/format.hpp>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/filters/passthrough.h>
#include <pcl/sample_consensus/model_types.h>
#include <pcl/sample_consensus/method_types.h>
#include <pcl/segmentation/sac_segmentation.h>
struct VelodynePointXYZIRT
{
PCL_ADD_POINT4D
PCL_ADD_INTENSITY;
uint16_t ring;
float time;
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
} EIGEN_ALIGN16;
POINT_CLOUD_REGISTER_POINT_STRUCT (VelodynePointXYZIRT,
(float, x, x) (float, y, y) (float, z, z) (float, intensity, intensity)
(uint16_t, ring, ring) (float, time, time)
)
ros::Publisher pub1;
using PointXYZIRT = VelodynePointXYZIRT;
void help (const sensor_msgs::PointCloud2ConstPtr& scan)
{
// Convert the sensor_msgs/PointCloud2 data to pcl/PointCloud
pcl::PointCloud<VelodynePointXYZIRT>::Ptr cloud(new pcl::PointCloud<VelodynePointXYZIRT>());
pcl::fromROSMsg (*scan, *cloud);
pcl::ModelCoefficients coefficients;
pcl::PointIndices inliers;
// Create the segmentation object
pcl::SACSegmentation< pcl::PointCloud<PointXYZIRT>> seg;
// Optional
seg.setOptimizeCoefficients (true);
// Mandatory
seg.setModelType (pcl::SACMODEL_PLANE);
seg.setMethodType (pcl::SAC_RANSAC);
seg.setDistanceThreshold (0.01);
seg.setInputCloud (cloud.makeShared ());
seg.segment (inliers, coefficients);
// Publish the model coefficients
pcl_msgs::ModelCoefficients ros_coefficients;
pcl_conversions::fromPCL(coefficients, ros_coefficients);
pub1.publish (ros_coefficients);
}
int main (int argc, char** argv)
{
// Initialize ROS
ros::init (argc, argv, "my_pcl_tutorial");
ros::NodeHandle nh;
// Create a ROS subscriber for the input point cloud
ros::Subscriber sub = nh.subscribe ("input", 1, help);
// Create a ROS publisher for the output point cloud
//#pub1 = nh.advertise<sensor_msgs::PointCloud2> ("output", 1);
pub1 = nh.advertise<pcl_msgs::ModelCoefficients> ("output", 1);
// Spin
ros::spin ();
}
as i have to put the ring data in the code, so i made the struct for defining the velodyne lidar,
but when i catkin_make in the ros,
this error comes,
error: ‘pcl::PointCloud<VelodynePointXYZIRT>::Ptr {aka class boost::shared_ptr<pcl::PointCloud<VelodynePointXYZIRT> >}’ has no member named ‘makeShared’
seg.setInputCloud (cloud.makeShared ());
is there a method that i visualize the data?
my reference for making the code is this site,https://adioshun.gitbooks.io/pcl-tutorial/content/part-1/part01-chapter05/part01-chapter05-practice.html
and my previous code to transform the lidar data, i used these code to make my own.....
#include <iostream>
#include <cmath>
#include <vector>
#include <ros/ros.h>
#include <sensor_msgs/PointCloud2.h>
#include <pcl_ros/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl_conversions/pcl_conversions.h>
#include <velodyne_pointcloud/point_types.h>
#include <pcl/common/common.h>
#include <pcl/common/centroid.h>
#include <pcl/common/transforms.h>
#include <pcl/console/parse.h>
#include <set>
#include <pcl/io/pcd_io.h>
#include <boost/format.hpp>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/filters/passthrough.h>
#define PI 3.14159265359
using namespace std;
struct VelodynePointXYZIRT
{
PCL_ADD_POINT4D
PCL_ADD_INTENSITY;
uint16_t ring;
float time;
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
} EIGEN_ALIGN16;
POINT_CLOUD_REGISTER_POINT_STRUCT (VelodynePointXYZIRT,
(float, x, x) (float, y, y) (float, z, z) (float, intensity, intensity)
(uint16_t, ring, ring) (float, time, time)
)
ros::Publisher pub1;
float theta_r = 45* M_PI/ 180; // 라디안 각도로 회전 (180도 회전)
using PointXYZIRT = VelodynePointXYZIRT;
void input(const sensor_msgs::PointCloud2ConstPtr& scan)
{
// Msg to pointcloud
pcl::PointCloud<VelodynePointXYZIRT>::Ptr cloud(new pcl::PointCloud<VelodynePointXYZIRT>());
pcl::fromROSMsg(*scan,*cloud); // ros msg 에서 pcl cloud 데이터로 변환
//회전변환행렬
Eigen::Matrix4f transform_1 = Eigen::Matrix4f::Identity();
// Define a rotation matrix (see https://en.wikipedia.org/wiki/Rotation_matrix)
transform_1 (0,0) = std::cos (theta_r);
transform_1 (0,2) = std::sin(theta_r);
transform_1 (2,0) = -sin (theta_r);
transform_1 (2,2) = std::cos (theta_r);
// (row, column)
// Executing the transformation
pcl::PointCloud<VelodynePointXYZIRT>::Ptr transformed_cloud (new pcl::PointCloud<PointXYZIRT>());
pcl::transformPointCloud (*cloud, *transformed_cloud, transform_1);
pcl::PCLPointCloud2 cloud_p;
pcl::toPCLPointCloud2(*transformed_cloud, cloud_p);
sensor_msgs::PointCloud2 output;
pcl_conversions::fromPCL(cloud_p, output);
output.header.frame_id = "velodyne";
pub1.publish(output);
}
int main(int argc, char** argv)
{
ros::init(argc, argv, "input");
ros::NodeHandle nh;
ros::Subscriber sub = nh.subscribe<sensor_msgs::PointCloud2> ("vlp202", 100, input);
pub1 = nh.advertise<sensor_msgs::PointCloud2> ("vlp203", 100);
ros::spin();
}
//if you have to make your own type of custum point type in the pcl, you can see this one to see how to code it !!
// also the ring data that you have to use is from the lio_sam, image projection.cpp
so for the abstract,
i want to remove floor point cloud data in recorded bag,
so i made some code to remove floor data
The "cloud" object is already a shared pointer. Remove makeShared call:
seg.setInputCloud (cloud.makeShared ());
to
seg.setInputCloud (cloud);
For visualization you could publish over a topic the result as ros message and visualize it with rviz.

How to get list element from rosparam parameter from the cmd?

I loaded this yaml file:
num_boxes: 1
boxes: [[x: 0.349, y: 0.213, z: 0.117]]
with rosparam load my_config.yaml then I can do rosparam get boxes and get:
- - {x: 0.349}
- {y: 0.213}
- {z: 0.117}
But how can I access only the first list or elements in the second list? I tried boxes[0], boxes(0) and boxes{0} but nothing worked.
This is an old question, but I'm answering it because it's still useful to put an answer here.
Using the example given, boxes is a list of lists (YAML syntax). From the rosparam command line tool, we can't process rosparam get /boxes any further (excepting grep and regex). In common use, we can access the Parameter Server in C++ / Python.
# Python
>>> import rospy
>>> boxes = rospy.get_param("/boxes"); boxes
[[{'x': 0.349}, {'y': 0.213}, {'z': 0.117}]]
# Boxes is a python list/array of list of dicts
>>> boxes[0]
[{'x': 0.349}, {'y': 0.213}, {'z': 0.117}]
>>> boxes[0][0]
{'x': 0.349}
// C++
#include <vector>
#include <ros/ros.h>
// yaml_list: [1, 2]
ros::NodeHandle *nh;
std::vector<int> yaml_list;
double x = 0.0;
int main(int argc, char** argv){
ros::init(argc, argv, "get_params_node");
nh = new ros::NodeHandle("");
nh->getParam("/yaml_list", yaml_list);
x = yaml_list[0];
// ...
return 0;
}
To have deeper data structures, such as vectors of vectors of maps, you have to use the xmlrpcpp (.h/.cpp) interface.
// C++
#include <vector>
#include <map>
#include <string>
#include <ros/ros.h>
#include <xmlrpcpp/XmlRpcValue.h> // catkin component
ros::NodeHandle *nh;
XmlRpc::XmlRpcValue boxes; // std::vector<std::vector<std::map<std::string,double>>>
double x = 0.0;
int i = 0;
double point[3] = {0};
int main(int argc, char** argv){
ros::init(argc, argv, "get_params_node");
nh = new ros::NodeHandle("");
nh->getParam("/boxes", boxes);
if(boxes.getType() == XmlRpc::XmlRpcValue::Type::TypeArray && boxes.size() > 0){
// boxes[0] is a 'TypeArray' aka vector
if(boxes[0].getType() == XmlRpc::XmlRpcValue::Type::TypeArray && boxes[0].size() > 0){
// boxes[0][0] is a 'TypeStruct' aka map
if(boxes[0][0].getType() == XmlRpc::XmlRpcValue::Type::TypeStruct && boxes[0][0].hasMember("x")){
x = double(boxes[0][0]["x"]);
for(XmlRpc::XmlRpcValue::iterator it = boxes[0][0].begin(); it != boxes[0][0].end(); ++it){
point[i++] = double(*it);
}
}
}
}
// ...
return 0;
}
In standard use, the <rosparam> XML tag keeps the same YAML or rosparam command line syntax.

Unable to access Kinect Sensor cam Using Opencv and libfreenect driver On Ubuntu platform

I am using OpenCv and OpenKinect on Ubuntu platform to access Kinect sensor. The major error is: undefined reference to `freenect_sync_get_rgb_cv' Help me to debug this error. The Source code is as given below:
#include <iostream>
#include <cv.h>
#include <opencv/highgui.h>
// OpenKinect Header files
#include <libfreenect.h>
#include <libfreenect_sync.h>
#include <libfreenect/libfreenect_cv.h>
// --- C++ ---
#include <stdio.h>
#include <fstream>
#include <vector>
#include <math.h>
#include <iostream>
#include <vector>
#include <opencv2/highgui.hpp>
using namespace std;
using namespace cv;
char key;
// IplImage *freenect_sync_get_depth_cv(int index);
// IplImage *freenect_sync_get_rgb_cv(int index);
int main(int argc, char** argv)
{
IplImage* image = NULL;
/* create a window */
cvNamedWindow("Camera_Output", 1);
while(1) {
image = freenect_sync_get_rgb_cv(0);
// Mat image(freenect_sync_get_rgb_cv(0));
//CvCapture* capture = cvCaptureFromCAM(CV_CAP_ANY);
// cvCvtColor(image, image, CV_RGB2BGR); // cvLoadImage( freenect_sync_get_rgb_cv(0) )
// VideoCapture::grab
//cvCreateImage(cvSize(640, 480), 8, 4);
cvShowImage("Camera_Output", image);
if (!image) {
printf("Error: Kinect not connected?\n");
return -1;
}
key = cvWaitKey(100); //Capture Keyboard stroke
if (char(key) == 27){
break;
}
}
/* free memory */
cvDestroyWindow( "video" );
return 0;
}
The error looks like:
[100%] Building CXX object CMakeFiles/KinectRGB.dir/KinectRGB.cpp.o
Linking CXX executable KinectRGB
CMakeFiles/KinectRGB.dir/KinectRGB.cpp.o: In function `main':
KinectRGB.cpp:(.text+0x2c): undefined reference to `freenect_sync_get_rgb_cv'
collect2: error: ld returned 1 exit status
make[2]: *** [KinectRGB] Error 1
make[1]: *** [CMakeFiles/KinectRGB.dir/all] Error 2
make: *** [all] Error 2
sincos#sincos-300E4C-300E5C-300E7C:~/Desktop/OpenCV_test/KinectRead/build$
CMakeLists.txt file to Build the code is as given below:
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
project(KinectRGB)
set(DEPENDENCIES OpenCV GLUT OpenGL)
message("\n")
foreach( DEP ${DEPENDENCIES} )
find_package( ${DEP} )
string( TOUPPER ${DEP} UDEP ) # Capitalize
if( ${DEP}_FOUND OR ${UDEP}_FOUND )
message("\n${DEP}_Found = TRUE\n")
endif()
find_package(Threads REQUIRED)
find_package(libfreenect REQUIRED)
include_directories("/usr/include/libusb-1.0/")
endforeach()
include_directories(
${FREENECT_INCLUDE_DIR}
${GLUT_INCLUDE_DIR}
${OPENGL_INCLUDE_DIR}
${OpenCV_INCLUDE_DIRS}
)
add_executable(KinectRGB KinectRGB.cpp)
target_link_libraries(KinectRGB
${FREENECT_LIBRARIES}
${GLUT_LIBRARY}
${OPENGL_LIBRARIES}
${OpenCV_LIBS}
${CMAKE_THREAD_LIBS_INIT}
)
I would not recommend using IplImage. It is a primitive class type. To test whether your Kinect is working properly, run the following python script:
import freenect
import cv2
import numpy as np
from functions import *
def nothing(x):
pass
kernel = np.ones((5, 5), np.uint8)
def pretty_depth(depth):
np.clip(depth, 0, 2**10 - 1, depth)
depth >>= 2
depth = depth.astype(np.uint8)
return depth
while 1:
dst = pretty_depth(freenect.sync_get_depth()[0])#input from kinect
cv2.imshow('Video', dst)
if cv2.waitKey(1) & 0xFF == ord('b'):
break
You should see the kinect's disparity map

OpenCV: How to use cvSobel?

I'm trying to find the gradient direction from the edges using OpenCv 2.4.5, but I'm having problem with cvSobel() and below is the error message and my code. I read somewhere that it might be due to the conversion between floating point(??) but I have no idea on how to fix it. Any Help??
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2\opencv.hpp>
#include <opencv2\calib3d\calib3d.hpp>
#include <iostream>
#include <stdlib.h>
#include "stdio.h"
using namespace cv;
using namespace std;
int main()
{
Mat im = imread("test1.jpg");
if (im.empty()) {
cout << "Cannot load image!" << endl;
}
Mat *dx, *dy;
dx = new Mat( Mat::zeros(im.rows, im.cols, 1));
dy = new Mat( Mat::zeros(im.rows, im.cols, 1));
imshow("Image", im);
// Convert Image to gray scale
Mat im_gray;
cvtColor(im, im_gray, CV_RGB2GRAY);
imshow("Gray", im_gray);
//trying to find the direction, but gives errors here
cvSobel(&im_gray, dx, 1,0,3);
waitKey(0);
return 0;
}
You are mixing the C++ and C api. cv::Mat is from the C++ api and CvArr* is from the C api.
here you are using The C api cvSobel on C++ classes.
//trying to find the direction, but gives errors here
cvSobel(&im_gray, dx, 1,0,3);
What happens if you do
cv::Sobel( im_gray, dx, im_gray.depth(), 1, 0, 3);
EDIT
and declare
Mat dx;
Mat dy;
I think this might solve your problem, I'm actually quite surprised your code compiles.

lua5.2's error: multiple Lua VMs detected

I use 5.2 for learning recently, what I want to try like this:
Step 1, build a c module for lua:
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#include <stdlib.h>
static int add(lua_State *L) {
int x = luaL_checkint(L, -2);
int y = luaL_checkint(L, -1);
lua_pushinteger(L, x + y);
return 1;
}
static const struct luaL_Reg reg_lib[] = {
{"add", add}
};
int luaopen_tool(lua_State *L) {
luaL_newlib(L, reg_lib);
lua_setglobal(L, "tool");
return 0;
}
I compile and link it with liblua.a, and I'm sure it works well in lua script like "require("tool") tool.add(1, 2)"
Step 2, I write another C program that wants to require my c module in step 1 like this:
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#include <stdlib.h>
int main(int argc, char* const argv[]) {
lua_State *L = luaL_newstate();
luaL_requiref(L, "base", luaopen_base, 1);
luaL_requiref(L, "package", luaopen_package, 1);
lua_getglobal(L, "require");
if (!lua_isfunction(L, -1)) {
printf("require not found\n");
return 2;
}
lua_pushstring(L, "tool");
if (lua_pcall(L, 1, 1, 0) != LUA_OK) {
printf("require_fail=%s\n", lua_tostring(L, -1));
return 3;
}
lua_getfield(L, -1, "add");
lua_pushinteger(L, 2);
lua_pushinteger(L, 3);
lua_pcall(L, 2, 1, 0);
int n = luaL_checkint(L, -1);
printf("n=%d\n", n);
return 0;
}
I also compile & link with liblua.a, but error occurs when I run it:
"require_fail=multiple Lua VMs detected"
Someone's blog said that in lua5.2, you should link c module and c host program both dynamicly, but not staticly.
is there someone that has the same problem, or is there somehing wrong in my code, thanks.
NOTICE:
the problem has been solved by compile main program with -Wl,-E, thanks a lot for all your help ^^.
Don't link your C module with liblua.a when you create a .so from it. For examples, see my page of Lua libraries: http://www.tecgraf.puc-rio.br/~lhf/ftp/lua/ . You can link liblua.a statically into your main program but you have to export its symbols by adding -Wl,-E at link time. That's how the Lua interpreter is built in Linux.

Resources