I'm trying to accelerate an opencv program I wrote using OpenACC, I'm using the accull compiler to do this. However, I'm having a very hard time finding any documentation or examples that would help me on this issue.
http://scelementary.com/2015/04/30/openacc-on-jetson-tk1.html
I don't have any experience with ACCULL, but I can provide you with an example that uses OpenCV and OpenACC and maybe that'll help you get moving. This has been tested on X86 with PGI on Ubunut 14.04. This will read an image, invert the pixels, and write an image back out.
invert.cpp:
void invert(unsigned char *imgData, int w, int h, int ch, int step)
{
int i,j,c;
#pragma acc parallel loop collapse(3) copy(imgData[:h*w*ch])
for ( i = 0; i < h; i++)
for ( j = 0; j < w; j++ )
for ( c = 0; c < ch; c++ )
imgData[i*step + j*ch + c] = 255 - imgData[i*step + j*ch + c];
}
main.cpp:
#include <stdio.h>
#include <opencv/cv.h>
#include <opencv/cvaux.h>
#include <opencv/highgui.h>
void invert(unsigned char*,int,int,int,int);
int main(int argc, char* argv[])
{
if (argc < 3)
{
fprintf(stderr,"Usage: %s inFilename outFilename\n",argv[0]);
return -1;
}
IplImage* img = cvLoadImage(argv[1]);
printf("%s: %d x %d, %d %d\n", argv[1],img->width, img->height, img->widthStep, img->nChannels);
invert((unsigned char*)img->imageData,img->width,img->height, img->nChannels, img->widthStep);
if(!cvSaveImage(argv[2],img))
fprintf(stderr,"Failed to write to %s.\n",argv[2]);
cvReleaseImage(&img);
return 0;
}
Makefile:
a.out: main.cpp invert.cpp
pgc++ -fast -ta=tesla -c invert.cpp
pgc++ -fast -ta=tesla -c main.cpp
pgc++ -ta=tesla invert.o main.o -lopencv_legacy -lopencv_highgui -lopencv_core
Related
I am trying to make use of openpose example in opencv using caffe model and opencv/dnn.hpp
tutorial I have been following - https://www.learnopencv.com/deep-learning-based-human-pose-estimation-using-opencv-cpp-python/
we require 2 files for the network as said in the tutorial :
1 - prototxt - https://github.com/spmallick/learnopencv/blob/master/OpenPose/pose/coco/pose_deploy_linevec.prototxt
2 - caffe model - posefs1.perception.cs.cmu.edu/OpenPose/models/pose/coco/pose_iter_440000.caffemodel
ros node that I made following the tutorial :
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/dnn/dnn.hpp>
#include <sensor_msgs/image_encodings.h>
#include <ros/ros.h>
#include <image_transport/image_transport.h>
#include <cv_bridge/cv_bridge.h>
#include <iostream>
using namespace std;
using namespace cv;
using namespace cv::dnn;
static const std::string OPENCV_WINDOW = "Image window";
#define COCO
#ifdef COCO
const int POSE_PAIRS[17][2] =
{
{1,2}, {1,5}, {2,3},
{3,4}, {5,6}, {6,7},
{1,8}, {8,9}, {9,10},
{1,11}, {11,12}, {12,13},
{1,0},{0,14},
{14,16}, {0,15}, {15,17}
};
static const std::string protoFile = "pose/coco/pose_deploy_linevec.prototxt";
static const std::string weightsFile = "pose/coco/pose_iter_440000.caffemodel";
int nPoints = 18;
#endif
class ImageConverter
{
ros::NodeHandle nh_;
image_transport::ImageTransport it_;
image_transport::Subscriber image_sub_;
public:
ImageConverter()
: it_(nh_)
{
image_sub_ = it_.subscribe("/zed/rgb/image_raw_color", 1, &ImageConverter::imageCb, this);
}
~ImageConverter()
{
cv::destroyWindow(OPENCV_WINDOW);
}
void imageCb(const sensor_msgs::ImageConstPtr& msg)
{
cv_bridge::CvImagePtr cv_ptr;
try
{
cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8);
}
catch (cv_bridge::Exception& e)
{
ROS_ERROR("cv_bridge exception: %s", e.what());
return;
}
if (cv_ptr->image.rows > 60 && cv_ptr->image.cols > 60)
detect_people(cv_ptr->image);
cv::waitKey(3);
}
void detect_people(cv::Mat msg)
{
int inWidth = msg.cols;
int inHeight = msg.rows;
float thresh = 0.1;
cv::Mat frame;
msg.copyTo(frame);
cv::Mat frameCopy = frame.clone();
int frameWidth = frame.cols;
int frameHeight = frame.rows;
cv::dnn::Net net = cv::dnn::readNetFromCaffe("pose_deploy_linevec.prototxt" ,"pose_iter_440000.caffemodel");
cv::Mat inpBlob = blobFromImage(frame, 1.0/255, cv::Size(inWidth, inHeight), cv::Scalar(0, 0, 0), false, false);
net.setInput(inpBlob);
cv::Mat output = net.forward();
int H = output.size[2];
int W = output.size[3];
std::vector<cv::Point> points(nPoints);
for (int n=0; n < nPoints; n++)
{
// Probability map of corresponding body's part.
cv::Mat probMap(H, W, CV_32F, output.ptr(0,n));
cv::Point2f p(-1,-1);
cv::Point maxLoc;
double prob;
cv::minMaxLoc(probMap, 0, &prob, 0, &maxLoc);
if (prob > thresh)
{
p = maxLoc;
p.x *= (float)frameWidth / W ;
p.y *= (float)frameHeight / H ;
cv::circle(frameCopy, cv::Point((int)p.x, (int)p.y), 8, Scalar(0,255,255), -1);
cv::putText(frameCopy, cv::format("%d", n), cv::Point((int)p.x, (int)p.y), cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(0, 0, 255), 2);
}
points[n] = p;
}
int nPairs = sizeof(POSE_PAIRS)/sizeof(POSE_PAIRS[0]);
for (int n = 0; n < nPairs; n++)
{
// lookup 2 connected body/hand parts
Point2f partA = points[POSE_PAIRS[n][0]];
Point2f partB = points[POSE_PAIRS[n][1]];
if (partA.x<=0 || partA.y<=0 || partB.x<=0 || partB.y<=0)
continue;
cv::line(frame, partA, partB, cv::Scalar(0,255,255), 8);
cv::circle(frame, partA, 8, cv::Scalar(0,0,255), -1);
cv::circle(frame, partB, 8, cv::Scalar(0,0,255), -1);
}
cv::imshow("Output-Skeleton", frame);
}
};
int main(int argc, char** argv)
{
ros::init(argc, argv, "image_converter");
ros::NodeHandle nh_;
ros::Publisher pub;
ImageConverter ic;
ros::spin();
return 0;
}
The code is compiled without any errors, but while I run the code it gives the following error msg :
I get the following error when I run the node
error - OpenCV Error: Unspecified error (FAILED: fs.is_open(). Can't open "pose_deploy_linevec.prototxt") in ReadProtoFromTextFile, file /tmp/binarydeb/ros-kinetic-opencv3-3.3.1/modules/dnn/src/caffe/caffe_io.cpp, line 1119
terminate called after throwing an instance of 'cv::Exception'
what(): /tmp/binarydeb/ros-kinetic-opencv3-3.3.1/modules/dnn/src/caffe/caffe_io.cpp:1119: error: (-2) FAILED: fs.is_open(). Can't open "pose_deploy_linevec.prototxt" in function ReadProtoFromTextFile
Aborted (core dumped)
please help me solve this issue.
This issue is probably with the windows users only.
Solve the issue by:
Using/Adding absolute path when calling prototxt file.
Add the extension too. For Example:
"pose/coco/pose_deploy_linevec.prototxt.txt"
Spent 3 hours debugging this myself. Hope it helped someone else.
You are selecting the wrong file path.
Just replace this line:
static const std::string protoFile = "pose/coco/pose_deploy_linevec.prototxt";
with the path of the prototxt file in your laptop like this:
static const std::string protoFile = "C:/Users/lenovo/Desktop/learnopencv-master/OpenPose/pose/coco/pose_deploy_linevec.prototxt";
I have recently used this piece of code to save frame data from a webcam
#include <opencv\cv.h>
#include <opencv\highgui.h>
#include <opencv2/opencv.hpp>
using namespace cv;
#include <fstream>
using namespace std;
int main(int argc, char** argv)
{
VideoCapture cap(0); // open the default camera
if (!cap.isOpened()) // check if we succeeded
return -1;
cap.set(CV_CAP_PROP_FPS, 15);
Mat edges;
namedWindow("image", 1);
std::vector<cv::Mat> images(100);
for (int i = 0; i < 100; ++i) {
// this is optional, preallocation so there's no allocation
// during capture
images[i].create(480, 640, CV_8UC3);
}
for (int i = 0; i < 100; ++i)
{
Mat frame;
cap >> frame; // get a new frame from camera
frame.copyTo(images[i]);
}
cap.release();
for (int i = 0; i < 100; ++i)
{
imshow("image", images[i]);
if (waitKey(30) >= 0) break;
}
After this, I want to use imread to analyse the newly splitted frames. However, I cannot think of a way to accomplish this.
I tried: Mat colorImage = imread(images[i]);
However, it leads to:
error C2664: 'cv::Mat cv::imread(const cv::String &,int)': cannot convert argument 1 from 'std::vector<cv::Mat,std::allocator<_Ty>>' to 'const cv::String &'
with
[
_Ty=cv::Mat
]
Thanks a lot in advance :)
imread function is used to open the image from disk.
You already have vector of images so you just do:
Mat colorImage = images[i];
and btw. there is no need for this:
for (int i = 0; i < 100; ++i) {
// this is optional, preallocation so there's no allocation
// during capture
images[i].create(480, 640, CV_8UC3);
}
because you are allocating new space anyway except you capture the frames directly like this:
cap >> images[i];
I need help to get the coordinates of the lines that HoughLines produced and extract it to an output file (Notepad, Excel, or any other output files).
I managed to obtain the lines and based on my research on this site I found a post that tells how to obtain the coordinates, however due to my limited understanding I could not get the code to run along my original Hough code and get the intersection points coordinate onto an output file.
Here is my original Hough code:
#pragma once
#include <C:\OpenCV2.2\include\opencv\cv.h>
#include <C:\OpenCV2.2\include\opencv\highgui.h>
#include <C:\OpenCV2.2\include\opencv2\core\core.hpp>
#include <C:\OpenCV2.2\include\opencv2\imgproc\imgproc.hpp>
#include <C:\OpenCV2.2\include\opencv2\highgui\highgui.hpp>
#include <stdio.h>
#include <math.h>
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main(int argc, char* argv[])
{
cv::Mat dst_img, gray_img, contour_img, contrast_img;
cv::Mat src_img = cv::imread("C:\\Frame-1.bmp"); //Source image path
dst_img = src_img.clone();
dst_img.convertTo(contrast_img, -1, 1.5, 0);
cv::cvtColor(contrast_img, gray_img, CV_BGR2GRAY);
cv::Canny(gray_img, contour_img, 75, 225, 3);
vector<Vec2f> lines_;
HoughLines(contour_img, lines_, 1, CV_PI/180, 200);
for( size_t i = 0; i < lines_.size(); i++ )
{
float rho = lines_[i][0];
float theta = lines_[i][1];
double a = cos(theta), b = sin(theta);
double x0 = a*rho, y0 = b*rho;
Point pt1(cvRound(x0 + 1000*(-b)),
cvRound(y0 + 1000*(a)));
Point pt2(cvRound(x0 - 1000*(-b)),
cvRound(y0 - 1000*(a)));
cv::clipLine(gray_img.size(), pt1, pt2);
if(!dst_img.empty())
line( dst_img, pt1, pt2, Scalar(0, 0, 255), 1, CV_AA);
cv::imwrite("result.bmp", dst_img);
}
namedWindow("My Image");
imshow("My Image", dst_img);
waitKey(0);
return 0;
}
And here is the link to the code that I wanted to put into my original code:
I am struck at finding the point of intersection of most lines in an image
Right now my original code draws Houghlines and exports the image (as result.bmp) and at the same time displays the image on a new window.
I just need to figure how and where to put the new code plus an additional code to obtain the raw data of the coordinates onto an output file like Notepad, most desirably in the same folder as result.bmp (the name of the output file could be anything, just needed it to be there).
Sorry if this question sounds like a beginner`s question (I really am) and any help is much appreciated. Many thanks in advance.
Additional information: I am using OpenCV 2.2 and Microsoft Visual Studio Academic 2010
EDIT: This is all three codes (Hough, Coordinate extraction, and Exporting data to notepad) but as a complete beginner I don`t know to make them all work in a single code.
#pragma once
#include <C:\OpenCV2.2\include\opencv\cv.h>
#include <C:\OpenCV2.2\include\opencv\highgui.h>
#include <C:\OpenCV2.2\include\opencv2\core\core.hpp>
#include <C:\OpenCV2.2\include\opencv2\imgproc\imgproc.hpp>
#include <C:\OpenCV2.2\include\opencv2\highgui\highgui.hpp>
#include <stdio.h>
#include <math.h>
#include <opencv2/opencv.hpp>
#include <iostream>
#define PointMinusPoint(P,Q,R) {(P).x = (Q).x - (R).x; (P).y = (Q).y - (R).y;}
#define PointCross(P,Q) (((P).x*(Q).y)-((P).y*(Q).x))
#define SIGN(X) (((X)>=0)? 1:-1 )
#define ABS(a) ((a) >= 0 ? (a) : (-(a)))
#define ROUND(a) ((SIGN(a)) * ( ( int )( ABS(a) + 0.5 ) ) )
typedef struct{
int x,y;
} MYintPOINT;
typedef struct {
MYintPOINT pStart;
MYintPOINT pEnd;
} MyLine;
using namespace std;
using namespace cv;
int main(int argc, char* argv[])
{
cv::Mat dst_img, gray_img, contour_img, contrast_img;
cv::Mat src_img = cv::imread("C:\\Frame-1.bmp"); //Source image path
dst_img = src_img.clone();
dst_img.convertTo(contrast_img, -1, 1.5, 0);
cv::cvtColor(contrast_img, gray_img, CV_BGR2GRAY);
cv::Canny(gray_img, contour_img, 75, 225, 3);
vector<Vec2f> lines_;
HoughLines(contour_img, lines_, 1, CV_PI/180, 200);
for( size_t i = 0; i < lines_.size(); i++ )
{
float rho = lines_[i][0];
float theta = lines_[i][1];
double a = cos(theta), b = sin(theta);
double x0 = a*rho, y0 = b*rho;
Point pt1(cvRound(x0 + 1000*(-b)),
cvRound(y0 + 1000*(a)));
Point pt2(cvRound(x0 - 1000*(-b)),
cvRound(y0 - 1000*(a)));
cv::clipLine(gray_img.size(), pt1, pt2);
if(!dst_img.empty())
line( dst_img, pt1, pt2, Scalar(0, 0, 255), 1, CV_AA);
cv::imwrite("result.bmp", dst_img);
}
int findLinesIntersectionPoint(const MyLine*l1, const MyLine*l2, MYintPOINT *res){
MYintPOINT p = l1->pStart;
MYintPOINT dp;
MYintPOINT q = l2->pStart;
MYintPOINT dq;
MYintPOINT qmp; // q-p
int dpdq_cross; // 2 cross products
int qpdq_cross; // dp with dq, q-p with dq
float a;
PointMinusPoint(dp,l1->pEnd,l1->pStart);
PointMinusPoint(dq,l2->pEnd,l2->pStart);
PointMinusPoint(qmp,q,p);
dpdq_cross = PointCross(dp,dq);
if (!dpdq_cross){
// Perpendicular Lines
return 0;
}
qpdq_cross = PointCross(qmp,dq);
a = (qpdq_cross*1.0f/dpdq_cross);
res->x = ROUND(p.x+a*dp.x);
res->y = ROUND(p.y+a*dp.y);
return 1;
}
string FileName= FileName_S.c_str();
string::size_type Extension = FileName_S.find_last_of('.'); // Find extension point
Mat mInputImg;
mInputImg= imread(FileName_S,1);
Size szInput= mInputImg.size();
const string DestinationFileName = FileName_S.substr(0, Extension) + "_ImageData.csv"; // Form the new name with container
ofstream myfile (DestinationFileName.c_str());
if (!myfile.is_open())
{
MessageBox(L"Unable to Open File");
}
string Text= format("Row, Col , Pixel Data,\n");
myfile << Text;
for (int Row = 0; Row < szInput.height; Row++)
{
for (int Col = 0; Col < szInput.width; Col++)
{
string Text= format("%d , %d , %d",Row,Col,mInputImg.at<uchar>(Row,Col));
myfile << Text;
myfile << "\n";
}
}
myfile.close();
namedWindow("My Image");
imshow("My Image", dst_img);
waitKey(0);
return 0;
}
It is very easy to export your data to Notepad or excel file. Here is the code to Export a mat to a csv File. Format your String with your desired data to export your desired data.
/*Exporting a Mat to Excel(.csv) file*/
string FileName= FileName_S.c_str();
string::size_type Extension = FileName_S.find_last_of('.'); // Find extension point
Mat mInputImg;
mInputImg= imread(FileName_S,1);
Size szInput= mInputImg.size();
const string DestinationFileName = FileName_S.substr(0, Extension) + "_ImageData.csv"; // Form the new name with container
ofstream myfile (DestinationFileName.c_str());
if (!myfile.is_open())
{
MessageBox(L"Unable to Open File");
}
string Text= format("Row, Col , Pixel Data,\n");
myfile << Text;
for (int Row = 0; Row < szInput.height; Row++)
{
for (int Col = 0; Col < szInput.width; Col++)
{
string Text= format("%d , %d , %d",Row,Col,mInputImg.at<uchar>(Row,Col));
myfile << Text;
myfile << "\n";
}
}
myfile.close();
My speedup-example.cpp source code is shown below
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <assert.h>
#include "tern/user.h"
#define N 8
#define M 10000
int nwait = 0;
int nexit = 0;
volatile long long sum;
long loops = 6e3;
pthread_mutex_t mutex;
pthread_cond_t cond;
pthread_barrier_t bar;
void set_affinity(int core_id) {
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(core_id, &cpuset);
assert(pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset) ==0);
}
void* thread_func(void *arg) {
set_affinity((int)(long)arg);
for (int j = 0; j < M; j++) {
pthread_mutex_lock(&mutex);
nwait++;
for (long i = 0; i < loops; i++) // This is the key of speedup for parrot: the mutex needs to be a little bit congested.
sum += i;
pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);
soba_wait(0);
pthread_barrier_wait(&bar);
for (long i = 0; i < loops; i++)
sum += i*i*i*i*i*i;
//fprintf(stderr, "compute thread %u %d\n", (unsigned)thread, sched_getcpu());
}
}
int main(int argc, char *argv[]) {
set_affinity(23);
soba_init(0, N, 20);
pthread_t th[N];
int ret;
pthread_cond_init(&cond, NULL);
pthread_barrier_init(&bar, NULL, N);
for(unsigned i=0; i<N; ++i) {
ret = pthread_create(&th[i], NULL, thread_func, (void*)i);
assert(!ret && "pthread_create() failed!");
}
for (int j = 0; j < M; j++) {
while (nwait < N) {
sched_yield();
}
pthread_mutex_lock(&mutex);
nwait = 0;
//fprintf(stderr, "broadcast %u %d\n", (unsigned)pthread_self(), sched_getcpu());
pthread_cond_broadcast(&cond);
pthread_mutex_unlock(&mutex);
}
for(unsigned i=0; i<N; ++i)
pthread_join(th[i], NULL);
exit(0);
}
I already succeeded wrote the mk of speedup-example.cpp
gcc speedup-example.cpp -o speedup-example -O2 -g \-I$XTERN_ROOT/include -L$XTERN_ROOT/dync_hook -Wl,--rpath,$XTERN_ROOT/dync_hook -lxtern-annot \-lpthread
But when I want to run it, problems occur.
For example
$ time ./speedup-example
It informs me that
speedup-example.cpp:23: void set_affinity(int): Assertion `pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset) ==0' failed.
Can someone help me solve this problem? Many thanks.
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.