How to use remove_if with vector<point2f> - opencv

I have a vector that has lots of NaN's for x,y positions that I want to remove(doing some opencv work). I cannot figure out how to use remove_if to remove the NaNs(when used in conjunction with erase). I've seen lots of examples if the vector is float or int but not point2f. Any simple examples would be very helpful. Thanks.

You can use a lambda function, or a functor or a function pointer. This is an example with a lambda function:
#include <opencv2/opencv.hpp>
#include <algorithm>
#include <iostream>
#include <cmath>
using namespace cv;
using namespace std;
int main(int argc, char ** argv)
{
vector<Point2f> pts{ Point2f(1.f, 2.f), Point2f(3.f, sqrt(-1.0f)), Point2f(2.f, 3.f) };
cout << "Before" << endl;
for (const auto& p : pts) {
cout << p << " ";
}
cout << endl;
pts.erase(remove_if(pts.begin(), pts.end(), [](const Point2f& p)
{
// Check if a coordinate is NaN
return isnan(p.x) || isnan(p.y);
}), pts.end());
cout << "After" << endl;
for (const auto& p : pts) {
cout << p << " ";
}
cout << endl;
return 0;
}
That will print:
Before
[1, 2] [3, -1.#IND] [2, 3]
After
[1, 2] [2, 3]

Related

LNK2019 error when using cuda::calcHist() opencv4.1.0+cuda [duplicate]

I'm pretty new to OpenCV and I wanted to implement houghlines for a project. I pulled the houghlines.cpp from the OpenCV Docs. When I run the source file I seem to get an error. I run it on Visual Studios 15 and am using OpenCV 3.1. I don't really know much about Cuda and have just been introduced into the world of OpenCV, so I do require a more thorough guidance. Thank You.
#include <cmath>
#include <iostream>
#include "opencv2/core.hpp"
#include <opencv2/core/utility.hpp>
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/cudaimgproc.hpp"
using namespace std;
using namespace cv;
using namespace cv::cuda;
static void help()
{
cout << "This program demonstrates line finding with the Hough transform." << endl;
cout << "Usage:" << endl;
cout << "./gpu-example-houghlines <image_name>, Default is ../data/pic1.png\n" << endl;
}
int main(int argc, const char* argv[])
{
const string filename = argc >= 2 ? argv[1] : "../data/pic1.png";
Mat src = imread(filename, IMREAD_GRAYSCALE);
if (src.empty())
{
help();
cout << "can not open " << filename << endl;
return -1;
}
Mat mask;
cv::Canny(src, mask, 100, 200, 3);
Mat dst_cpu;
cv::cvtColor(mask, dst_cpu, COLOR_GRAY2BGR);
Mat dst_gpu = dst_cpu.clone();
vector<Vec4i> lines_cpu;
{
const int64 start = getTickCount();
cv::HoughLinesP(mask, lines_cpu, 1, CV_PI / 180, 50, 60, 5);
const double timeSec = (getTickCount() - start) / getTickFrequency();
cout << "CPU Time : " << timeSec * 1000 << " ms" << endl;
cout << "CPU Found : " << lines_cpu.size() << endl;
}
for (size_t i = 0; i < lines_cpu.size(); ++i)
{
Vec4i l = lines_cpu[i];
line(dst_cpu, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0, 0, 255), 3, LINE_AA);
}
GpuMat d_src(mask);
GpuMat d_lines;
{
const int64 start = getTickCount();
Ptr<cuda::HoughSegmentDetector> hough = cuda::createHoughSegmentDetector(1.0f, (float)(CV_PI / 180.0f), 50, 5);
hough->detect(d_src, d_lines);
const double timeSec = (getTickCount() - start) / getTickFrequency();
cout << "GPU Time : " << timeSec * 1000 << " ms" << endl;
cout << "GPU Found : " << d_lines.cols << endl;
}
vector<Vec4i> lines_gpu;
if (!d_lines.empty())
{
lines_gpu.resize(d_lines.cols);
Mat h_lines(1, d_lines.cols, CV_32SC4, &lines_gpu[0]);
d_lines.download(h_lines);
}
for (size_t i = 0; i < lines_gpu.size(); ++i)
{
Vec4i l = lines_gpu[i];
line(dst_gpu, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0, 0, 255), 3, LINE_AA);
}
imshow("source", src);
imshow("detected lines [CPU]", dst_cpu);
imshow("detected lines [GPU]", dst_gpu);
waitKey();
return 0;
}
Error LNK2019
unresolved external symbol "struct cv::Ptr __cdecl cv::cuda::createHoughSegmentDetector(float,float,int,int,int)" (?createHoughSegmentDetector#cuda#cv##YA?AU?$Ptr#VHoughSegmentDetector#cuda#cv###2#MMHHH#Z) referenced in function main
An additional library must be linked when compiling.
In Windows, the library name is opencv_cudaimgproc310.lib. If one is using Visual Studio, the library name must be added at [Configuration Properties] -> [Linker] -> [Input] -> [Additional Dependencies].
In Linux, it is typically libopencv_cudaimgproc.so, which is a symbolic link to libopencv_cudaimgproc.so.3.1, which in turn is a symbolic link to libopencv_cudaimgproc.so.3.1.0, which is the actual library. If one is using g++, -lopencv_cudaimgproc must be added to g++ command.
I'm assuming that, in both environment, library search path is set properly, that is, it contains path to the OpenCV libraries.

The result of opencv3.3 dnn module not match the caffe prediction

I used opencv dnn classification, but the result do not match the caffe prediction. What confused me was that some images could get similar result to caffe,a small number of images not.When I changed BGR to RGB, Most of the results ware wrong.
similar result:
different result:
blobFromImage(norm_img, 1.0, cv::Size(64, 64));when used default parameters changed BGR to RGB ,but the result would wrong .so I used like this blobFromImage(norm_img, 1.0, cv::Size(64, 64), cv::Scalar(),false); .most of result would matched caffe prediction,why a small number of images not?
#include <opencv2/dnn.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/core/utils/trace.hpp>
using namespace cv;
using namespace cv::dnn;
#include <fstream>
#include <iostream>
#include <cstdlib>
using namespace std;
/* Find best class for the blob (i. e. class with maximal probability) */
static void getMaxClass(const Mat &probBlob, int *classId, double *classProb)
{
Mat probMat = probBlob.reshape(1, 1); //reshape the blob to 1x1000 matrix
Point classNumber;
minMaxLoc(probMat, NULL, classProb, NULL, &classNumber);
*classId = classNumber.x;
}
static std::vector<String> readClassNames(const char *filename = "./config/type.txt")
{
std::vector<String> classNames;
std::ifstream fp(filename);
if (!fp.is_open())
{
std::cerr << "File with classes labels not found: " << filename << std::endl;
exit(-1);
}
std::string name;
while (!fp.eof())
{
std::getline(fp, name);
if (name.length())
classNames.push_back(name.substr(name.find(' ') + 1));
}
fp.close();
return classNames;
}
int main(int argc, char **argv)
{
CV_TRACE_FUNCTION();
String modelTxt = "./config/HCCR3755_res20_deploy.prototxt";
String modelBin = "./config/HCCR3755-res20_iter_790000.caffemodel";
String imageFile = "./config/b9.jpg";
Net net = dnn::readNetFromCaffe(modelTxt, modelBin);
if (net.empty())
{
std::cerr << "Can't load network by using the following files: " << std::endl;
std::cerr << "prototxt: " << modelTxt << std::endl;
std::cerr << "caffemodel: " << modelBin << std::endl;
exit(-1);
}
Mat img = imread(imageFile);
FileStorage fs("./config/mean.xml", FileStorage::READ);
Mat _mean;
fs["vocabulary"] >> _mean;
if (img.empty())
{
std::cerr << "Can't read image from the file: " << imageFile << std::endl;
exit(-1);
}
cv::Mat img_resize;
resize(img, img_resize, Size(64, 64));
cv::Mat img_float;
img_resize.convertTo(img_float, CV_32FC3);
cv::Mat norm_img;
cv::subtract(img_float, _mean, norm_img);
Mat inputBlob = blobFromImage(norm_img, 1.0, cv::Size(64, 64), cv::Scalar(),false); //Convert Mat to batch of images
Mat prob;
cv::TickMeter t;
for (int i = 0; i < 1; i++)
{
CV_TRACE_REGION("forward");
//! [Set input blob]
net.setInput(inputBlob, "data"); //set the network input
//! [Set input blob]
t.start();
//! [Make forward pass]
prob = net.forward("prob");
//std::cout << prob << std::endl;//compute output
//! [Make forward pass]
t.stop();
}
int classId;
double classProb;
getMaxClass(prob, &classId, &classProb);//find the best class
//! [Gather output]
//! [Print results]
std::vector<String> classNames = readClassNames();
std::cout << "Best class: #" << classId << " '" << classNames.at(classId) << "'" << std::endl;
std::cout << "Probability: " << classProb * 100 << "%" << std::endl;
//! [Print results]
std::cout << "Time: " << (double)t.getTimeMilli() / t.getCounter() << " ms (average from " << t.getCounter() << " iterations)" << std::endl;
getchar();
return 0;
} //main

How to initialize a cv::Mat using a vector of floats?

Is there a way of initializing a opencv cv::Mat using a vector<float> object?
Or do I need to loop over every entry of the vector and write it into the cv::Mat object?
I wrote the following test code ( including #Miki 's comment ) to myself to understand in detail.
you will understand well when you test it.
#include <opencv2/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main(int argc, char* argv[])
{
vector<float> vec{0.1,0.9,0.2,0.8,0.3,0.7,0.4,0.6,0.5,1};
Mat m1( vec );
imshow("m1",m1);
waitKey();
Mat m2( 1,vec.size(), CV_32FC1,vec.data());
imshow("m2",m2);
waitKey();
Mat1f m3( vec.size(), 1, vec.data());
imshow("m3",m3);
waitKey();
Mat1f m4( 1, vec.size(), vec.data());
imshow("m4",m4);
waitKey();
cout << "as seen below all Mat and vector use same data" << endl;
cout << vec[0] << endl;
m1 *= 2;
cout << vec[0] << endl;
m2 *= 2;
cout << vec[0] << endl;
m3 *= 2;
cout << vec[0] << endl;
m4 *= 2;
cout << vec[0] << endl;
return 0;
}

Reading a file in chunks and appending the incomplete line to the next read

I am trying to read in from the following file:
abcdefghijklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxyz
12345abcdefghijklmnopqrstu
abcdefghijklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxyz
The code is below:
#include <iostream>
#include <fstream>
#include <sstream>
#include <thread>
#include <mutex>
#include <vector>
#include <array>
#include <algorithm>
#include <iterator>
#define CHUNK_SIZE 55
std::mutex queueDumpMutex;
void getLinesFromChunk(std::vector<char>& chunk, std::vector<std::string>& container)
{
static std::string str;
unsigned int i = 0;
while(i < chunk.size())
{
str.clear();
size_t chunk_sz = chunk.size();
while(chunk[i] != '\n' && i < chunk_sz )
{
str.push_back(chunk[i++]);
}
std::cout<<"\nStr = "<<str;
if (i < chunk_sz)
{
std::lock_guard<std::mutex> lock(queueDumpMutex);
container.push_back(str);
}
++i;
}
chunk.clear();
std::copy(str.begin(), str.end(), std::back_inserter(chunk));
std::cout << "\nPrinting the chunk out ....." << std::endl;
std::copy(chunk.begin(), chunk.end(), std::ostream_iterator<char>(std::cout, " "));
}
void ReadFileAndPopulateDump(std::ifstream& in)
{
std::vector<char> chunk;
chunk.reserve(CHUNK_SIZE*2);
std::vector<std::string> queueDump;
in.unsetf(std::ios::skipws);
std::cout << "Chunk capacity: " << chunk.capacity() << std::endl;
do{
in.read(&chunk[chunk.size()], CHUNK_SIZE);
std::cout << "Chunk size before getLines: " << chunk.size() << std::endl;
getLinesFromChunk(chunk, queueDump);
std::cout << "Chunk size after getLines: " << chunk.size() << std::endl;
}while(!in.eof());
}
int main()
{
std::ifstream in("/home/ankit/codes/more_practice/sample.txt", std::ifstream::binary);
ReadFileAndPopulateDump(in);
return 0;
}
What i wish to achieve is for the container to be line complete.
By this i mean that suppose my CHUNK_SIZE reads only:
abcdefghijklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxyz
12
The container should look like:
abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
instead of:
abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz12
Now i understand that chunk.reserve(CHUNK_SIZE) reserves the given memory and does not actually assign a SIZE. Because if this i am not able to read from in.read().
If i use chunk.resize(CHUNK_SIZE) and append it to the end as i want the remaining characters '12' to be appended with its complete line.
Now the issue is that the code is being repeated more than it should. According to me the conditions seem fine.
Any help will be much appreciated.
Sorry but I don't understand why do you:
read the file in binary mode and not in text mode
don't use getline()
use a vector<char> instead a string
For what I understand the problem you propose, I would do it this way
#include <cstdlib>
#include <fstream>
#include <iostream>
int main()
{
std::ifstream f("sample.txt"); // text mode!
std::size_t const chunkSizeMax = 55U;
std::string str;
std::string chunk;
while ( std::getline(f, str) )
{
if ( chunkSizeMax <= (chunk.size() + str.size()) )
{
std::cout << "chunk: [" << chunk << "]\n";
chunk.clear();
}
chunk += str;
}
std::cout << "last chunk: [" << chunk << "]\n";
return EXIT_SUCCESS;
}
Hoping this helps.

Copy select rows into new matrix

I want to copy the rows 0, 2 and 4 of my matrix A into B, in this order.
Let A = [a0, a1, a2, a3, a4]^T , with a_i being row-vectors,
then B should be: [a0, a2, a4]^T.
The code below does what I want but I wonder whether there is a prettier solution (maybe using Eigen)?
#include <iostream>
#include <vector>
#include <opencv/cv.h>
int main(int argc, char **argv) {
const int num_points = 5;
const int vec_length = 3;
cv::Mat A(num_points, vec_length, CV_32FC1);
cv::RNG rng(0); // Fill A with random values
rng.fill(A, cv::RNG::UNIFORM, 0, 1);
// HACK Ugly way to fill that matrix .
cv::Mat B = cv::Mat(3,vec_length, CV_32FC1);
cv::Mat tmp0 = B(cv::Rect(0,0,vec_length,1));
cv::Mat tmp1 = B(cv::Rect(0,1,vec_length,1));
cv::Mat tmp2 = B(cv::Rect(0,2,vec_length,1));
A.row(0).copyTo(tmp0);
A.row(2).copyTo(tmp1);
A.row(4).copyTo(tmp2);
std::cout << "A: " << A << std::endl;
std::cout << "B: " << B << std::endl;
return 0;
}
The way in OpenCV 2.4.1 is:
A.row(0).copyTo(B.row(0));
A.row(2).copyTo(B.row(1));
A.row(4).copyTo(B.row(2));
I found push_back.
Create B with size 0 x vec_length and then use push_back to add the selected rows from A:
#include <iostream>
#include <vector>
#include <opencv/cv.h>
int main(int argc, char **argv) {
const int num_points = 5;
const int vec_length = 3;
cv::Mat A(num_points, vec_length, CV_32FC1);
cv::RNG rng(0); // Fill A with random values
rng.fill(A, cv::RNG::UNIFORM, 0, 1);
cv::Mat B = cv::Mat(0,vec_length, CV_32FC1);
B.push_back(A.row(0));
B.push_back(A.row(2));
B.push_back(A.row(4));
std::cout << "A: " << A << std::endl;
std::cout << "B: " << B << std::endl;
return 0;
}
Since they are non-contiguous I don't think there's any shortcut. In this particular case you could make the code cleaner with a loop:
for (int i=0; i<3; i++) {
cv::Mat tmp = B(cv::Rect(0,i,vec_length,1));
A.row(i * 2).copyTo(tmp);
}
Mat row = old.row(0);
old.row(0).copyTo(row);
new.push_back(row);

Resources