error: 'QRCodeDetector' is not a member of 'cv' - c++

I am trying to use the opencv QRCodeDetector class in one of my functions, but unfortunately I am getting an error.
The error is saying that QRCodeDetector is not a member of cv.
C++ function code (test_qr.cpp):
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/objdetect.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
#include <vector>
#include <string>
void qrCheck(std::vector<std::string>& qrStorage, cv::Mat imageLeft_t0) {
cv::QRCodeDetector qrDecoder = cv::QRCodeDetector(); // Error on this line
std::string data = qrDecoder.detectAndDecode(imageLeft_t0);
if (data.length() > 0) {
std::cout << "QR Decoded Data: " << data << std::endl;
qrStorage.push_back(data);
} else
std::cout << "QR Code Not Detected" << std::endl;
}
In case you want to see my cmake file:
cmake_minimum_required(VERSION 3.11)
project( DisplayImage )
set(CMAKE_CXX_STANDARD 11)
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
add_executable( DisplayImage test_qr.cpp )
target_link_libraries( DisplayImage ${OpenCV_LIBS} )
I also tried doing something similar to this: ‘BackgroundSubtractorMOG’ is not a member of ‘cv’
But it didn't help.

Related

How to link boost libraries in VScode using vcpkg & cmake?

I am trying to use boost libraries in VSCode (using Cmake & vcpkg) but can't seem to figure out what's wrong. I installed Boost in vcpkg.
Here are the error messages.
main.cpp
#include <boost/multiprecision/cpp_int.hpp>
using namespace boost::multiprecision;
using namespace std;
int128_t boost_product(long long A, long long B)
{
int128_t ans = (int128_t) A * B;
return ans;
}
int main()
{
long long first = 98745636214564698;
long long second=7459874565236544789;
cout << "Product of "<< first << " * "
<< second << " = \n"
<< boost_product(first,second) ;
return 0;
}
setting.json
{
"C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools",
"cmake.configureSettings": {
"CMAKE_TOOLCHAIN_FILE": "C:/vcpkg/scripts/buildsystems/vcpkg.cmake"
}
}
CmakeLists.txt
cmake_minimum_required(VERSION 3.0.0)
project(demo VERSION 0.1.0)
include(CTest)
enable_testing()
add_executable(demo main.cpp)
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)
Errors:
main.cpp:1:10: fatal error: boost/multiprecision/cpp_int.hpp: No such file or directory
1 | #include <boost/multiprecision/cpp_int.hpp>
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
Maybe I am missing something. Please help.Thank you!

Objects not found in OpenCV4

This is my dir tree (root dir is untitled)
This is the content of CMakeLists.txt
cmake_minimum_required(VERSION 3.0.0)
project(untitled)
set(CMAKE_CXX_STANDARD 11)
find_package (OpenCV 4.5.2 REQUIRED)
include_directories ("/usr/local/include/opencv4/")
add_executable(untitled main.cpp)
This is my code in main.cpp:
#include <iostream>
#include <string>
#include <sstream>
#include <opencv4/opencv2/core.hpp>
#include <opencv4/opencv2/highgui.hpp>
using namespace cv;
using namespace std;
int main(int argc, const char** argv) {
Mat color = imread("./lenna.png");
Mat gray = imread("./lenna.png", 0);
imwrite("./lennaGray.png", gray);
int myRow = color.cols - 1;
int myCol = color.rows - 1;
Vec3b pixel = color.at<Vec3b>(myRow, myCol);
cout << "Pixel value (B, G, R): (" << (int)pixel[0] << ", " << (int)pixel[1] << ", " << (int)pixel[2] << ")" << endl;
imshow("Lenna BGR", color);
imshow("Lenna Gray", gray);
waitKey(0);
return 0;
}
This is the entire error when I ran make command:
But if I ran my code in terminal by this command:
g++ main.cpp -o main -lopencv_core -lopencv_highgui -lopencv_imgproc -lopencv_imgcodecs -I/usr/local/include/opencv4 && ./main
then it worked.
I don't know what happened, I just learned OpenCV and I am using Ubuntu 20.04 and OpenCV-4.5.2.

How to properly read a Point Cloud File in C++ and ROS

I just started using the Point Cloud Library and as a start I would like to read a point cloud from file. I followed the tutorial related to that. This is just a small example of a major CMake project I am building. Just slightly different from the tutorial I divided the project to make it more CMake suitable. The CMake runs well and the project seems to be organized. However when I try to run the project I get the following /home/emanuele/catkin_ws/src/map_ros/src/pointcloud_reader_node.cpp:6:10: fatal error: ../map_ros/include/cloud.h: No such file or directory #include "../map_ros/include/cloud.h"
error::Cloud::readPCloud(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) and I don't know how to explain this error.
Below the snippet of code I am using:
cloud.h
#ifndef CLOUD_H
#define CLOUD_H
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <sensor_msgs/PointCloud2.h>
#include <string>
class Cloud
{
public:
void readPCloud(std::string filename);
private:
std::string path;
};
#endif// CLOUD_H
cloud.cpp
#include "cloud.h"
void Cloud::readPCloud(std::string filename)
{
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
if(pcl::io::loadPCDFile<pcl::PointXYZ> (filename, *cloud) == -1) // load point cloud file
{
PCL_ERROR("Could not read the file");
return;
}
std::cout<<"Loaded"<<cloud->width * cloud->height
<<"data points from filename with the following fields: "
<<std::endl;
for(size_t i = 0; i < cloud->points.size(); ++i)
std::cout << " " << cloud->points[i].x
<< " " << cloud->points[i].y
<< " " << cloud->points[i].z << std::endl;
}
pointcloud_reader_node.cpp
#include <ros/ros.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include "../map_ros/include/cloud.h"
using namespace std;
int main()
{
std::string fstring = "/home/to/Desktop/file.pcd";
Cloud p;
p.readPCloud(fstring); // <-- Error Here
return 0;
}
Also for completeness I am adding the CMake file below:
cmake_minimum_required(VERSION 2.8.3)
project(map_ros)
add_compile_options(-std=c++11)
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR})
find_package(catkin REQUIRED COMPONENTS
// ....
)
catkin_package(
INCLUDE_DIRS include
LIBRARIES ${PROJECT_NAME}
CATKIN_DEPENDS
// ......
)
###########
## Build ##
###########
include_directories(${catkin_INCLUDE_DIRS})
add_executable(pointcloud_reader_node src/pointcloud_reader_node.cpp ${SRCS})
target_link_libraries(pointcloud_reader_node ${catkin_LIBRARIES})
I have figured out the problem to my question some time ago but wanted to share it in case someone has my same problem.
So there were two issues coming at the same time that made me think it was a CMake problem only:
1) catkin_make was not properly compiling not because of CMake as I thought for a long time, but because the cache file catkin_ws.workspace was causing problem to CMake itself. So the first solution to this problem was to erase the cache file catkin_ws.workspace and do a fresh compile. All CMake issues disappeared.
2) Second problem: The correct pseudo code for reading the point-cloud it was like:
main()
{
init node
create pointcloud publisher
create rate object with 1 second duration
load point cloud from file
while(ros::ok())
{
rate.sleep
publish point cloud message
}
}
And I realized nothing was being published on the input and the callback was executed.
Below the complete code that reads point-cloud from file and gives an output of all points to a .txt file. I hope this can be helpful to anyone who may encounter this problem:
test.cpp
#include <ros/ros.h>
#include <sensor_msgs/PointCloud2.h>
#include <pcl/io/pcd_io.h>
#include <pcl_conversions/pcl_conversions.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/filters/voxel_grid.h>
void loadFromFile(std::string filename)
{
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
if(pcl::io::loadPCDFile<pcl::PointXYZ> (filename, *cloud) == -1) // load point cloud file
{
PCL_ERROR("Could not read the file");
return;
}
std::cout<<"Loaded"<<cloud->width * cloud->height
<<"data points from /home/to/Desktop/point_cloud/yourFile.pcd with the following fields: "
<<std::endl;
// Write entire point clouds to a .txt file
std::ofstream myfile;
myfile.open ("/home/to/Desktop/exampleCloud.txt");
if (myfile.is_open()) {
for(size_t i = 0; i < cloud->points.size(); ++i)
myfile << " " << cloud->points[i].x
<< " " << cloud->points[i].y
<< " " << cloud->points[i].z << std::endl;
myfile.close();
}
}
int main (int argc, char** argv)
{
// Initialize ROS
ros::init (argc, argv, "pcl_tutorial_cloud");
ros::NodeHandle nh;
ros::Publisher pub = nh.advertise<sensor_msgs::PointCloud2>("output", 1000);
ros::Rate loop_rate(1);
loadFromFile("/home/to/Desktop/yourFile.pcd");
int count = 0;
while(ros::ok())
{
sensor_msgs::PointCloud2 pcloud2;
pub.publish(pcloud2);
ros::spinOnce();
loop_rate.sleep();
count ++;
}
return 0;
}
Here is the result after running :
1) catkin_make
2) rosrun yourProject test

Correct way to make library with priv / public header and pass cv::Mat

I need to make a .so or .a library and different headers, one of them to be shared with users to compile my main program (and link, in the code, processmatinlibrary_pub.h) and other to use in definitions and separated to the main code (processmatinlibrary.h).
When I use the public header (whitout some private definitions of methods), some times, depending on the structure of my program, I get segmentation faults or opencv assertions, below I paste my code, it could be dowloaded from https://github.com/eld1e6o/TestErrorOnLibrary
Here is my code and some comments
Files to create my main program, that uses functions on my library
This is the main function, I use it to check the library with public header
I get some segmentation faults depending on the structure of my program
I can force errors commenting #defines
#define _MAKE_ASSERT_OPENCV 1
#define _MAKE_SEGFAULT_ 1
*If I change the public header to the private header, I have not problems:
#include "processmatinlibrary.h" it works but the headers are not cshared
Instead of
#include "processmatinlibrary_pub.h"
It seems that is a stack problem and I need to define the library or the headers in the right way
Main.cpp
#include <opencv2/imgproc.hpp>
#include <opencv2/objdetect.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
#include "processmatinlibrary_pub.h" //If I change this header to #include "processmatinlibrary.h" it works but the headers are not cshared
using namespace std;
using namespace cv;
#define _MAKE_ASSERT_OPENCV 1
//#define _MAKE_SEGFAULT_ 1
void testEmpty(cv::Mat test_img, std::string msg)
{
cout << "* Check empty " << msg ;
if(test_img.empty())
{
cout << ": Image is Empty " << endl;
exit(1);
}
else cout << ": Image is not empty " << endl;
}
int main(int argc, char* argv[])
{
// Classify and get probabilities
Mat test_img = imread(argv[1], CV_LOAD_IMAGE_COLOR);
testEmpty(test_img, "After load image");
cv::resize(test_img, test_img, cv::Size(256, 256));
cout << " After resize " << endl;
testEmpty(test_img, "Before initialize library ");
ProcessMatInLibrary matToLibrary;
#ifdef _MAKE_SEGFAULT_
return 0; // If I comment this line, I got a segmentation fault: Segmentation Fault (`core' generated)
#endif
testEmpty(test_img, "After initialize library ");
bool b = matToLibrary.flip(test_img);
testEmpty(test_img, "After use function in library ");
cout << "In main " << endl;
/*
* If I define _MAKE_ASSERT_OPENCV, I got errors
OpenCV(3.4.1) Error: Assertion failed (0 <= _dims && _dims <= 32) in setSize, file /home/diego/Code/opencv/modules/core/src/matrix.cpp, line 209
terminate called after throwing an instance of 'cv::Exception'
what(): OpenCV(3.4.1) /home/diego/Code/opencv/modules/core/src/matrix.cpp:209: error: (-215) 0 <= _dims && _dims <= 32 in function setSize
*/
#ifndef _MAKE_ASSERT_OPENCV
imshow("Test before close", test_img); //If i comment this two lines, I got segmentation faults (OpenCV exception)
waitKey(0);
#endif
}
processmathlibrary_pub.h
This is my public header, used to define functions as publics
#ifndef PROCESSMATINLIBRARY_H
#define PROCESSMATINLIBRARY_H
#include <opencv2/imgproc.hpp>
#include <opencv2/objdetect.hpp>
#include <opencv2/highgui.hpp>
class ProcessMatInLibrary
{
public:
ProcessMatInLibrary();
bool flip(cv::Mat image);
bool myTest(cv::Mat one);
};
#endif // PROCESSMATINLIBRARY_H
Files to create my library
processmathinlibrary.cpp
#include "processmatinlibrary.h"
using namespace std;
using namespace cv;
#include <iostream>
ProcessMatInLibrary::ProcessMatInLibrary()
{
cout << "Initialized " << endl;
}
bool ProcessMatInLibrary::flip(cv::Mat image)
{
cout << "** Inside Library: " << endl;
if(image.empty())
{
cout << " Image is empty" << endl;
return false;
}
cout << " Image is not empty " << endl;
// return false;
Mat image2;
cv::flip(image, image2, 0);
imshow("Image in library", image);
imshow("Image2 in library", image2);
waitKey(0);
cout << "Inside Library: Image is not empty" << endl;
return true;
}
bool ProcessMatInLibrary::myTest(cv::Mat one)
{
one.copyTo(_img);
}
processmathlibrary.h
This is my private header, used to compile my library, it only differs on private declarations
#ifndef PROCESSMATINLIBRARY_LIB_H
#define PROCESSMATINLIBRARY_LIB_H
#include <opencv2/imgproc.hpp>
#include <opencv2/objdetect.hpp>
#include <opencv2/highgui.hpp>
class ProcessMatInLibrary
{
public:
ProcessMatInLibrary();
bool flip(cv::Mat image);
bool myTest(cv::Mat one);
private:
cv::Mat _img;
};
#endif // PROCESSMATINLIBRARY_LIB_H
How to compile all of this
CMakeLists.txt
Note that I have defined other PATH for OpenCV library, maybe there is an error to compile in the default PATH, I cannot check that
find_package(OpenCV REQUIRED) is working
cmake_minimum_required(VERSION 2.8.12)
project(test_pub_priv)
set(CMAKE_CXX_FLAGS "-Wall -Wextra -O3 -std=c++11")
#set(OpenCV_INCLUDE_DIRS "./include/")
find_package(OpenCV REQUIRED)
message(" ** Test with public private libraries ** ")
include_directories(${OpenCV_INCLUDE_DIRS})
aux_source_directory(./src SRC_LIST)
include_directories(./hpp SRC_LIST)
FILE(GLOB_RECURSE LibFiles "./hpp/*.h")
add_custom_target(headers SOURCES ${LibFiles})
add_library(myFramework ${SRC_LIST} )
add_executable(test_pub_priv ./examples/Main.cpp)
target_link_libraries(test_pub_priv ${OpenCV_LIBS} myFramework)
My question and problem is: What is the right way to pass a cv::Mat as argument trough library with one private header to the library and other (public header) to be shared?
Complete code can be seen here:
https://github.com/eld1e6o/TestErrorOnLibrary
Thanks!

Include Library in my C++ binary - Cmake

I am using the poppler-cpp library in my project.
It build & start it correctly, but I need to have popple installed in my system.
What is the way to import (include) the poppler library in my project, the aim is to execute it on another linux system which has not poppler lib installed, is it possible ?
My current cmakeList.txt file:
cmake_minimum_required(VERSION 3.5)
project(poppler_test)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/extra-cmake-modules/find-modules")
find_package(Poppler REQUIRED)
include(CMakeToolsHelpers OPTIONAL)
include_directories(${Poppler_INCLUDE_DIRS})
set(CMAKE_CXX_STANDARD 14)
set(SOURCE_FILES main.cpp)
ADD_LIBRARY(poppler STATIC IMPORTED)
add_dependencies( poppler poppler_test )
add_executable(poppler_test ${SOURCE_FILES})
target_link_libraries(${PROJECT_NAME} ${Poppler_LIBRARIES})
My main.cpp Programm
#include <algorithm>
#include <cpp/poppler-document.h>
#include <cpp/poppler-page.h>
#include <exception>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
using namespace std;
int main(int argc, char* argv[]) {
auto input = "/Home/Dev/poppler-test/test.pdf";
shared_ptr<poppler::document> doc{poppler::document::load_from_file(input)};
const int pagesNbr = doc->pages();
cout << "page count: " << pagesNbr << endl;
vector<string> infoKeys{doc->info_keys()};
for_each(infoKeys.begin(), infoKeys.end(),
[doc](string infoKey) { cout << doc->info_key(infoKey).to_latin1() << endl; });
for (int i = 0; i < pagesNbr; ++i) {
shared_ptr<poppler::page> currentPage{doc->create_page(i)};
if (currentPage == nullptr) {
auto byteArrayResult = currentPage->text().to_utf8();
string result{byteArrayResult.begin(), byteArrayResult.end()};
cout << result << endl;
}
}
}