I was trying the sample codes under opencv3.0.0-alpha while I encountered the following error:
ps#hp-pavilion:~/cvit/opencv_projects$ make stitch
g++ `pkg-config --cflags opencv` -o stitch stitch.cpp `pkg-config --libs opencv`
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o: In function `_start':
/build/glibc-qbmteM/glibc-2.21/csu/../sysdeps/x86_64/start.S:114: undefined reference to `main'
collect2: error: ld returned 1 exit status
makefile:5: recipe for target 'stitch' failed
make: *** [stitch] Error 1
I had simply copy-pasted the stitching.cpp file from opencv/samples/cpp and renamed and placed it as stitch.cpp in my projects folder where I also have my makefile. The makefile looks like :
CFLAGS = `pkg-config --cflags opencv`
LIBS = `pkg-config --libs opencv`
% : %.cpp
g++ $(CFLAGS) -o $# $< $(LIBS)
I compile .cpp files for instance temp.cpp simply by
make temp
and it works perfectly every time. But with this particular stitching code, the error pops-up each time. Here is the sample code -
#include <iostream>
#include <fstream>
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/stitching.hpp"
using namespace std;
using namespace cv;
bool try_use_gpu = false;
vector<Mat> imgs;
string result_name = "stitch_result.jpg";
void printUsage();
int parseCmdArgs(int argc, char** argv);
int main(int argc, char* argv[])
{
int retval = parseCmdArgs(argc, argv);
if (retval) return -1;
Mat pano;
Stitcher stitcher = Stitcher::createDefault(try_use_gpu);
Stitcher::Status status = stitcher.stitch(imgs, pano);
if (status != Stitcher::OK)
{
cout << "Can't stitch images, error code = " << int(status) << endl;
return -1;
}
imwrite(result_name, pano);
return 0;
}
void printUsage()
{
cout <<
"Rotation model images stitcher.\n\n"
"stitching img1 img2 [...imgN]\n\n"
"Flags:\n"
" --try_use_gpu (yes|no)\n"
" Try to use GPU. The default value is 'no'. All default values\n"
" are for CPU mode.\n"
" --output <result_img>\n"
" The default is 'result.jpg'.\n";
}
int parseCmdArgs(int argc, char** argv)
{
if (argc == 1)
{
printUsage();
return -1;
}
for (int i = 1; i < argc; ++i)
{
if (string(argv[i]) == "--help" || string(argv[i]) == "/?")
{
printUsage();
return -1;
}
else if (string(argv[i]) == "--try_use_gpu")
{
if (string(argv[i + 1]) == "no")
try_use_gpu = false;
else if (string(argv[i + 1]) == "yes")
try_use_gpu = true;
else
{
cout << "Bad --try_use_gpu flag value\n";
return -1;
}
i++;
}
else if (string(argv[i]) == "--output")
{
result_name = argv[i + 1];
i++;
}
else
{
Mat img = imread(argv[i]);
if (img.empty())
{
cout << "Can't read image '" << argv[i] << "'\n";
return -1;
}
imgs.push_back(img);
}
}
return 0;
}
Edit : I just tried running the sample code from the samples folder itself and it works. The makefile runs perfectly without any error if I place it in the opencv/samples/cpp folder , but doesn't when I copy - paste it to another location.
The error means that the linker can't find your main function. Even though stitch.cpp defines main (I assume), the linker can't find it. The reason is unclear, because of the way you constructed your Makefile. I would make these changes:
use CXXFLAGS and/or CPPFLAGS for C++, because CFLAGS is for C.
expand the pkg-config output in make, so you can see what your compiler is being asked to do.
Your Makefile would then look like this:
CXXFLAGS = $(shell pkg-config --cflags opencv)
LIBS = $(shell pkg-config --libs opencv)
% : %.cpp
g++ $(CXXFLAGS) -o $# $^ $(LIBS)
I would like to think that with these changes the actual source of the problem will become apparent.
Related
I am trying to create a point cloud using a stereo camera arrangement (calibrated and rectified), a disparity map, and Point Cloud Library. Below is a brief description of my C++ code that is supposed to generate a point cloud using the disparity map.
#include <iostream>
#include <fstream>
#include <string>
#include <opencv2/opencv.hpp>
#include <opencv2/ximgproc.hpp>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/visualization/cloud_viewer.h>
#include <boost/thread/thread.hpp>
#include <pcl/visualization/vtk.h>
using namespace std;
using namespace cv;
using namespace cv::ximgproc;
using namespace pcl;
using namespace pcl::visualization;
boost::shared_ptr<PCLVisualizer> rgbVis (PointCloud<PointXYZRGB>::ConstPtr cloud)
{
boost::shared_ptr<PCLVisualizer> viewer (new PCLVisualizer ("3D Viewer"));
viewer->setBackgroundColor (0, 0, 0);
PointCloudColorHandlerRGBField<PointXYZRGB> rgb(cloud);
viewer->addPointCloud<PointXYZRGB> (cloud, rgb, "sample cloud");
viewer->setPointCloudRenderingProperties (PCL_VISUALIZER_POINT_SIZE, 3, "sample cloud");
return (viewer);
}
/* Some other functions */
int main()
{
.....
.....
int l, r;
cout << "Enter CAM index for Left Camera ";
cin >> l;
cout << endl << "Enter CAM index for Right Camera ";
cin >> r;
VideoCapture leftCam(l);
VideoCapture rightCam(r);
........
........
boost::shared_ptr<PCLVisualizer> viewer;
bool proceed = true;
while(proceed)
{
........
........
PointCloud<PointXYZRGB>::Ptr pointCloud(new PointCloud<PointXYZRGB>());
Mat xyz;
reprojectImageTo3D(disparityMap, xyz, q);
pointCloud->width = static_cast<uint32_t>(disparityMap.cols);
pointCloud->height = static_cast<uint32_t>(disparityMap.rows);
pointCloud->is_dense = false;
PointXYZRGB tempPoint;
for(int i = 0; i < disparityMap.rows; i++)
{
uchar* rgb_ptr = rightUndistorted.ptr<uchar>(i);
uchar* disp_ptr = disparityMap.ptr<uchar>(i);
double* xyz_ptr = xyz.ptr<double>(i);
for(int j = 0; j < disparityMap.cols; j++)
{
uchar d = disp_ptr[j];
if(d == 0)
continue;
Point3f p = xyz.at<Point3f>(i, j);
tempPoint.x = p.x;
tempPoint.y = p.y;
tempPoint.z = p.z;
tempPoint.b = rgb_ptr[3 * j];
tempPoint.g = rgb_ptr[3 * j + 1];
tempPoint.r = rgb_ptr[3 * j + 2];
pointCloud->points.push_back(tempPoint);
}
}
viewer = rgbVis(pointCloud);
if(waitKey(50) == 'q')
proceed = false;
}
destroyAllWindows();
return 0;
}
I run the following terminal command to compile this .cpp file...
g++ -std=c++14 d2pc.cpp -o d2pc `pkg-config --cflags --libs opencv pcl_io-1.11 pcl_visualization-1.11` -lboost_system
This generates the following error message...
/usr/local/include/pcl-1.11/pcl/visualization/point_cloud_geometry_handlers.h:48:10: fatal error: vtkSmartPointer.h: No such file or directory
#include <vtkSmartPointer.h>
^~~~~~~~~~~~~~~~~~~
compilation terminated.
I thought that installing Vtk from here might help solve the issue, but it didn't help.
How to tackle this issue? I am using OpenCV 3.4.10 in Ubuntu 18.04
First build and install vtk:
Build
tar xf VTK-9.0.1.tar.gz
cd VTK-9.0.1
mkdir build && cd build
cmake ..
make -j
Install
(if you have a different preferred place for installations than ~/.local, just change insdir below)
insdir=$(echo ~/.local)
mkdir $insdir
cmake --install . --prefix $insdir
Then add the include path (-I $insdir/include/vtk-9.0), the library path (-L $insdir/lib64 or possibly $insdir/lib on a 32 bit machine) and vtk libraries (-llibname1 ... -llibnameX) to your compilation command.
Example:
allvtklibs=$(ls $insdir/lib64/libvtk*.so | sed -E 's,^.*/lib(.*)\.so$,-l\1,')
g++ -std=c++14 d2pc.cpp -o d2pc -I $insdir/include/vtk-9.0 -L $insdir/lib64 $(pkg-config --cflags --libs opencv pcl_io-1.11 pcl_visualization-1.11) -Wl,-rpath=$insdir/lib64 $allvtklibs -lboost_system
I haven't ever used ffmpeg on my own laptop. All's ok at work, but here I met an ugly problem: library works but helpless:)
Ubuntu 18.04, ffmpeg 4.1 (downloaded sources, ./configure, make, sudo make install), it seems to be ok.
Application returns:
File /home/ahlininv/Desktop/video_example.mp4 is encodec with '' codec, w = 0, h = 0
I ran it under debugger. If I set format to zero, pointer changes after calling avformat_open_input(&format, file, 0, &dict), so it works and maybe works correct.
Maybe it plays any role that compiler says that av_register_all, avcodec_register_all are deprecated, but I thought it's not significant problem.
I tried to change version of ffmpeg (tried to install it with apt-get, version 3.somenumber is available), nothing changed.
I tried to run another video file (.avi), nothing changed, too.
Guys, help=) How to this file's info correctly?
main.cpp:
#include "filereader.h"
int main(int argc, char** argv) {
std::string filename = "/home/ahlininv/Desktop/video_example.mp4";
std::string codec;
int w, h;
bool open_ok = get_file_info(filename.c_str(), codec, w, h);
if (!open_ok) {
std::cout << "Failed to open file" << "\n";
return 1;
}
std::cout << "File " << filename << " is encoded with '" << codec << "' codec, w = " << w << ", h = " << h << "\n";
return 0;
}
filereader.h:
#ifndef FILEREADER_H
#define FILEREADER_H
#include <string>
#include <iostream>
extern "C" {
#ifndef __STDC_CONSTANT_MACROS
#define __STDC_CONSTANT_MACROS
#endif
#include "libavcodec/avcodec.h"
#include <libavformat/avformat.h>
#include <libavutil/avutil.h>
}
bool get_file_info(const char* file, std::string& codec, int& w, int& h);
#endif // FILEREADER_H
filereader.cpp
#include "filereader.h"
bool get_file_info(const char* file, std::string& codec, int& w, int& h)
{
codec = "";
w = h = 0;
av_register_all();
avcodec_register_all();
AVDictionary* dict = 0;
AVFormatContext* format = avformat_alloc_context();
char errbuf[256];
int r = avformat_open_input(&format, file, 0, &dict);
if (r!=0){
av_strerror(r, errbuf, sizeof(errbuf));
std::cout << "avformat_open_input error: " << errbuf << "\n";
}
if (r == AVERROR(EIO) || r == AVERROR(ENOEXEC) || !format)
return false;
for (size_t c = 0; c < format->nb_streams; ++c)
{
if (format->streams[c]->codecpar && format->streams[c]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
{
if (format->streams[c]->codecpar->codec_id != AV_CODEC_ID_NONE &&
format->streams[c]->codecpar->codec_id != AV_CODEC_ID_RAWVIDEO)
{
w = format->streams[c]->codecpar->width;
h = format->streams[c]->codecpar->height;
codec = avcodec_get_name(format->streams[c]->codecpar->codec_id);
}
}
}
avformat_close_input(&format);
return true;
}
Compile:
g++ -o filereader main.cpp filereader.cpp -lavutil -lavformat -lavcodec -lavdevice -lz -lm -pthread -lswresample -lm -lz -I /usr/local/include/ -Wl,-rpath /usr/lib/x86_64-linux-gnu/
Can you add these lines Before for loop on filereader.cpp to see if it makes any difference.
if (avformat_find_stream_info(format, NULL) < 0)
{
//handle error
}
How do I run a non-legacy PassManager? I have tried doing the following but there is some exception thrown when trying to invalidate the analysis manager in the run function. Is there something else I should do for initialization?
llvm::AnalysisManager<Module> mm;
PassBuilder builder;
auto pm = builder.buildModuleOptimizationPipeline(PassBuilder::OptimizationLevel::O3);
pm.run(module, mm );
These snippets illustrate how to run and setup to run modern custom function and module pass on some .c/.cpp file... complete with a makefile. This works for LLVM 6 which is pretty recent (march 2018). It does not use the legacy pass manager.
HelloWorld.cpp:
#include <llvm/Pass.h>
#include <llvm/IR/Function.h>
#include <llvm/IR/Module.h>
#include <llvm/Support/raw_ostream.h>
namespace {
struct Hello : public llvm::FunctionPass {
static char ID;
Hello() : llvm::FunctionPass{ID} {}
bool runOnFunction(llvm::Function &F) override {
llvm::errs() << "Hello ";
llvm::errs().write_escaped(F.getName()) << "\n";
return false;
}
};
struct Hello2 : public llvm::ModulePass {
static char ID;
Hello2() : llvm::ModulePass{ID} {}
bool runOnModule(llvm::Module &M) override {
llvm::errs() << "Name of the module ", llvm::errs().write_escaped(M.getName()) << "\n";
for(auto iter = M.getFunctionList().begin(); iter != M.getFunctionList().end(); ++iter) {
llvm::errs() << "Function name:" << iter->getName() << "\n";
}
return false;
}
};
}
char Hello::ID = 0;
static llvm::RegisterPass<Hello> X("Hello",
"Hello World Pass",
false,
false
);
char Hello2::ID = 1;
static llvm::RegisterPass<Hello2> Y("Hello2",
"Hello World2 pass",
false,
false
);
Corresponding makefile:
LLVM_VERSION=
LLVM_INCLUDEDIR = `llvm-config-6.0 --includedir`
LLVM_FLAGS = `llvm-config-6.0 --cxxflags --ldflags --system-libs --libs all`
CXX = clang++-6.0
CXXFLAGS = -g -std=c++11 -O3 -I $(LLVM_INCLUDEDIR) -I $(LLVM_INCLUDEDIR)
Hello.so:
$(CXX) -fPIC $(CXXFLAGS) HelloWorld.cpp $(LLVM_FLAGS) -shared -o Hello.so
Hello: Hello.so
testfile:
clang++-6.0 -emit-llvm -c test.cpp -o test.bc
runFunctionPassOnTestFile: Hello testfile
opt-6.0 -load ./Hello.so -Hello < test.bc > /dev/null
runModulePassOnTestfile: Hello testfile
opt-6.0 -load ./Hello.so -Hello2 < test.bc > /dev/null
clean:
rm *.o *.so *.out *~
DBG:
#echo LLVM INCLUDE DIRS $(LLVM_INCLUDEDIR) $(test)
A simple file to test everything on, test.cpp:
#include <stdio.h>
#include <stdlib.h>
int a = 4;
int c = 5;
int d = 6;
int e = 7;
int bar() { int *a = (int*) malloc(4); e = 1; return 1;}
int foo() { return 2; }
int barfoo() { return 3; }
int main() {
printf("Testing testing\n");
return 0;
}
I'm using nanomsg for request/receive and the code I have works just fine when I compiled it using a Makefile. However when I try using cmake, it compiles just fine but runs into Segmentation Fault when trying to send a message.
Does anyone know what's going on? I'm also unsure if the issue is in my cmake file or in the .cc files.
Here is a minimal working example.
request.cc (its .h file is omitted here)
Requester::Requester(const char* url) {
int socket = nn_socket(AF_SP, NN_REQ);
assert(socket >= 0);
assert(nn_connect (socket, url) >= 0);
}
Requester::~Requester() {
nn_shutdown(socket, 0);
}
const char* Requester::request_for_sentence(const char* sentence){
int size_sentence = strlen(sentence) + 1;
int bytes = nn_send(socket, sentence, size_sentence, 0); # segmentation fault occurs here
assert(bytes == size_sentence);
char *buf = NULL;
bytes = nn_recv(socket, &buf, NN_MSG, 0);
assert(bytes >= 0);
printf("REQUESTER RECEIVED %s\n", buf);
return buf;
}
request_test.cc
int main(int argc, char** argv) {
extractor::Requester my_requester("ipc:///tmp/extractor.ipc");
const char* output = my_requester.request_for_sentence("some input");
cerr << "output: " << output << endl;
return 0;
}
receiver.cc
int main(int argc, char** argv) {
const char* url = "ipc:///tmp/extractor.ipc";
int socket = nn_socket (AF_SP, NN_REP);
assert(socket >= 0);
assert(nn_bind (socket, url) >= 0);
while(1){
char *buf = NULL;
int bytes = nn_recv(socket, &buf, NN_MSG, 0);
assert (bytes >= 0);
const char* grammar_for_sentence = extract_for_sentence(buf);
cerr << grammar_for_sentence << endl;
int size_grammar = strlen(grammar_for_sentence) + 1; // '\0' too
bytes = nn_send(socket, grammar_for_sentence, size_grammar, 0);
assert(bytes == size_grammar);
nn_freemsg (buf);
}
return 0;
}
Makefile that works:
CC=g++
CFLAGS = -L$HOME/opt/lib -I$HOME/opt/include -lnanomsg
all : run_test run_extract_daemon
run_test : extract_request_test.cc extract_request.o
$(CC) $(CFLAGS) -o run_test extract_request_test.cc extract_request.o -I.
run_extract_daemon : extract_daemon.cc
$(CC) $(CFLAGS) -o run_extract_daemon extract_daemon.cc
extract_request.o : extract_request.cc extract_request.h
$(CC) $(CFLAGS) -c extract_request.cc
clean :
rm run_test run_extract_daemon extract_request.o
CMakeLists.txt that doesn't work:
find_package(nanomsg)
if(NANOMSG_FOUND)
include_directories(${NANOMSG_INCLUDE_DIR})
set(extract_request_test_SRCS extract_request_test.cc)
add_executable(run_extractor_request_test ${extract_request_test_SRCS})
target_link_libraries(run_extractor_request_test extractor ${NANOMSG_LIBRARIES})
set(extract_daemon_SRCS extract_daemon.cc)
add_executable(run_daemon ${extract_daemon_SRCS})
target_link_libraries(run_daemon extractor ${NANOMSG_LIBRARIES})
endif(NANOMSG_FOUND)
set(extractor_STAT_SRCS
extract_request.cc
extract_request.h)
add_library(extractor STATIC ${extractor_STAT_SRCS})
I face a error of "multiple definition of "
I got 3 files, namely currency.h, currency.cpp,main.cpp
At currencyConverter.h under currencyConverter class
I did
using namespace std;
class currencyConverter
{
string result;
stringstream ss;
size_t found,found2;
public:
void getInbetween(string,string);
};
#endif /* CURRENCYCONVERTER_H */
Then at currencyConverter.cpp I did
#include "currencyConverter.h"
void currencyConverter::getInbetween(string selection,string str2,string str3,string sdata)
{
buffer[result.length()] = '\0'; //insert '\0'
char * pch;
pch = strtok (buffer," ");
}
void currencyConverter::webparser(const string siteurl,const string filename)
{
ss << "lynx -dump '" << siteurl << "' > " << filename;
}
string currencyConverter::userOption()
{
//some code
return selection;
}
at main2.cpp
#include<iostream>
#include"currencyConverter.cpp"
using namespace std;
int main() {
currencyConverter c;
string exitstr;
if(selection!="6")
{
c.webparser(parsePage,"file.txt");
//now perform searchstring
c.searchString(selection,"file.txt");
}
}while (1);
return 0;
}
This is my make file
# ExampleTests Project
SRCS = main2.cpp
HDRS =
PROJ = main
CC = g++
OBJS = $(SRCS:.cpp=.o)
APP = $(PROJ).exe
CFLAGS = -c -g -Wall -I/opt/local/include
ifeq (,$(findstring CYGWIN,$(shell uname)))
LIBS = -lcppunit -ldl
all: $(APP)
$(APP): $(OBJS)
$(CC) $(LDFLAGS) $(OBJS) -o $(APP) $(LIBS)
clean:
rm -f *.o $(APP)
But i receive this error on compiler
How to get this fix.. I did not use it twice. I pasted part of my currencyConverter.cpp with the function webparser, is there a error in the way i call my function at main2.cpp ?
rm -f *.o main.exe
CLEAN SUCCESSFUL (total time: 86ms)
g++ -c -o main2.o main2.cpp
td::char_traits, std::allocator >)':
currencyConverter.cpp:(.text+0xcec): multiple definition of `currencyConverter::webparser(std::basic_string, std::allocator >, std::basic_string, std::allocator >)'
main2.o:main2.cpp:(.text+0xcec): first defined here
collect2: ld returned 1 exit status
make: * [main.exe] Error 1
Include a header file, not a cpp:
#include"currencyConverter.cpp"
should be
#include"currencyConverter.h"
in your main2.cpp