How can I store a big matrix within the .cc file? - opencv

I am currently working on a Computer Vision / Machine Learning project for university. Sadly, they only allow us to upload one single file and restrict the computation time too much. Hence I need to compute the matrices on my machine and store them in the same file as the code (22500 rows, 1 col and 100 rows + 22500 col and 100 rows + 1 col). I already found a way to export the data (link), but I'm not sure how to initialize the matrix.
What I've tried
#include <opencv/cv.h>
#include <opencv/highgui.h>
int main(int argc, char const *argv[])
{
float data[10] = {1,2,3,4,5,7,8,9,10,11};
cv::Mat A;
// Something is wrong with this line
A = cv::Mat(1, 10, cv::CV_32FC1, data);
return 0;
}
When I compile it, I get:
main.cc: In function ‘int main(int, const char**)’:
main.cc:10:16: error: expected primary-expression before ‘(’ token
A = cv::Mat(1, 10, cv::CV_32FC1, data);
^
In file included from /usr/include/opencv2/core/core_c.h:47:0,
from /usr/include/opencv/cv.h:63,
from main.cc:1:
main.cc:10:28: error: expected unqualified-id before ‘(’ token
A = cv::Mat(1, 10, cv::CV_32FC1, data);
^
Second try
#include <opencv/cv.h>
#include <opencv/highgui.h>
int main(int argc, char const *argv[])
{
float dataHeaderMat1[10] = {1,2,3,4,5,7,8,9,10,11};
cv::Mat matrix1;
// Something is wrong with this line
cv::cvInitMatHeader( &matrix1, 10, 1, CV_64FC1, dataHeaderMat1);
return 0;
}
gives
main.cc:10:5: error: ‘cvInitMatHeader’ is not a member of ‘cv’
cv::cvInitMatHeader( &matrix1, 10, 1, CV_64FC1, dataHeaderMat1);
^

The following works to declare and initialize a matrix:
#include <opencv/cv.h>
#include <opencv/highgui.h>
int main(int argc, char const *argv[])
{
float data[10] = {1,2,3,4,5,7,8,9,10,11};
cv::Mat A;
// Something is wrong with this line
A = cv::Mat(1, 10, CV_32FC1, data);
return 0;
}
However, I'm not too sure if this is the best way for big arrays.

You can try to save image to header file, like this:
#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
// uncomment for test
//#include "image.h"
int main(int argc, char **argv)
{
// This part creates header file from image.
Mat img=imread("D:\\ImagesForTest\\lena.jpg");
int w=img.cols;
int h=img.rows;
int channels=img.channels();
ofstream os("image.h");
os << "int rows=" << h << ";" << endl;
os << "int cols=" << w << ";" << endl;
os << "unsigned char d[]={" << endl;
for(int i=0;i<h;++i)
{
for(int j=0;j<w;++j)
{
if(i!=(w-1) || j!=(h-1))
{
Vec3b b=img.at<Vec3b>(i,j);
os << format("0x%02x,",b[0]);
os << format("0x%02x,",b[1]);
os << format("0x%02x,",b[2]);
}
}
}
Vec3b b=img.at<Vec3b>(w-1,h-1);
os << format("0x%02x,",b[0]);
os << format("0x%02x,",b[1]);
os << format("0x%02x",b[2]);
os << endl << "};" << endl;
os << "Mat I=Mat(rows,cols,CV_8UC3,d);" << endl;
os.close();
// To test uncomment commented part of code and comment uncommented.
// uncomment for test
/*
namedWindow("I");
imshow("I",I);
waitKey();
return 0;
*/
}
But be careful, not all IDEs likes such large files.

Related

readlink() error while reading /proc/self/exefile on QNX

I am working on QNX platform, in which I need to get the path of executable which is running.
I have wrote a small peice of code, which is returning always -1:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
extern int errno;
int main( int argc, char** argv )
{
char buf[512] = {0};
const char mypath[100] = "/proc/self/exefile";
errno = 0;
printf("The value readlink:: %d %s\n",readlink(mypath, buf, 512 ), strerror( errno ));
return( 0 );
}
When I ran above code then I get following output:
The value readlink:: -1 No such file or directory
Am I missing anything?
What needs to be done to get my current exe path in QNX?
In QNX /proc/self/exefile is not a symbolic link; It's a regular file.
Try:
#include <fstream>
#include <iostream>
#include <string>
int main(int argc, char **argv) {
std::ifstream file("/proc/self/exefile");
std::string path;
std::getline(file, path);
std::cout << path << "\n";
return 0;
}

IP camera keeps dropping frames

I am using an ethernet camera in opencv but I repeatedly get the following warning message when I run my program.
[rtp # 0x1a9c720] Received packet without a start chunk; dropping frame.
I think the problem might be with the rtp url I am using:
vcap.open("rtp://192.168.40.90:50004/");
I'm not even sure if I should be using rtp or something else.
#include "opencv2/opencv.hpp"
#include <iostream>
using namespace std;
using namespace cv;
int main(int argc, char *argv[])
{
VideoCapture vcap;
vcap.open("rtp://192.168.40.90:50004/"); // open IP cam
int numberOfFrames = 0;
for(;;)
{
Mat frame;
vcap >> frame;
cout << "number of frames = " << ++numberOfFrames << endl;
imshow( "display", frame );
char c = (char)waitKey(1);
if( c == 27 ) break;
}
vcap.release();
return 0;
}

how to track objects within the ROI using dlib?

I'm trying to get the stream and defining the ROI and tracking an object within ROI using dlib correlation tracker but there is a error in compilation, not found any code or explanation which can describe any solution of this error. Thanks in advance.
cvcap.cpp
#include <stdio.h>
#include <opencv2/opencv.hpp>
#include "dlib/image_processing.h"
#include "dlib/gui_widgets.h"
#include "dlib/image_io.h"
#include "dlib/dir_nav.h"
using namespace dlib;
using namespace std;
int main(int argc, char * argv[]){
CvCapture* camera = cvCaptureFromFile(argv[1]);
if (camera==NULL)
printf("camera is null\n");
else
printf("camera is not null\n");
cvNamedWindow("CvCapture");
while (cvWaitKey(1000)!=atoi("q")){
double t1 = (double)cvGetTickCount();
IplImage *img = cvQueryFrame(camera);
cvSetImageROI(img, cvRect(140, 150, 340, 150));
IplImage *img1 = cvCreateImage(cvGetSize(img), img->depth, img->nChannels);
cvCopy(img, img1, NULL);
cvResetImageROI(img);
cvShowImage("ROI",img1);
correlation_tracker tracker;
tracker.start_track(img1, centered_rect(point(120,100), 80, 150));
image_window win;
tracker.update(img1);
win.set_image(img1);
win.clear_overlay();
win.add_overlay(tracker.get_position());
cout << "hit enter to process next frame" << endl;
cin.get();
double t2=(double)cvGetTickCount();
printf("time: %gms fps: %.2g\n",(t2-t1)/(cvGetTickFrequency()*1000.), 1000./((t2-t1)/(cvGetTickFrequency()*1000.)));
cvShowImage("CvCapture",img1);
}
cvReleaseCapture(&camera);
}
the error is :
In file included from dlib/image_processing.h:24:0,
from cvcap.cpp:3:
dlib/image_processing/correlation_tracker.h: In instantiation of ‘dlib::point_transform_affine dlib::correlation_tracker::make_chip(const image_type&,
dlib::drectangle, std::vector<dlib::matrix<std::complex<double> > >&) const [with image_type = _IplImage*]’:
dlib/image_processing/correlation_tracker.h:65:47: required from ‘void dlib::correlation_tracker::start_track(const image_type&, const dlib::drectang
le&) [with image_type = _IplImage*]’
cvcap.cpp:36:70: required from here
dlib/image_processing/correlation_tracker.h:301:67: error: invalid use of incomplete type ‘struct dlib::image_traits<_IplImage*>’
typedef typename image_traits<image_type>::pixel_type pixel_type;
Update
i edited my code and now it is compiling but when i'm running my code, tracking box appears but it is not tracking the objects.
for(;;) {
if(!vcap.read(image)) {
std::cout << "No frame" << std::endl;
break;
} else {
std::cout << "Starting" << std::endl;
array2d<rgb_pixel> img;
assign_image(img, cv_image<rgb_pixel>(image));
tracker.start_track(img, centered_rect(point(413,260), 98, 126));
for (unsigned long i = 0; i < img.size(); i++) {
tracker.update(img);
win.set_image(img);
win.clear_overlay();
win.add_overlay(tracker.get_position());
}
}
}
You're passing an IplImage to the dlib routine. But if you look at the docs it says you have to convert your opencv images to cv_images before passing them to dlib functions. And you can see this with the error pointing out IplImage doesn't have a pixel_type trait. A fix would be.
IplImage *img1 = cvCreateImage(cvGetSize(img), img->depth, img->nChannels);
...
correlation_tracker tracker;
// Not sure if the tracker wants a single channel image
// change rgb_alpha_pixel to uchar in that case.
tracker.start_track(dlib::cv_image<dlib::rgb_alpha_pixel>(img1), centered_rect(point(120,100), 80, 150));
Pixel types and the Correlation tracker
EDIT: Passed your stuff to opencv 3 and this is compiling for me. Do you really need to use opencv 2?
#include <stdio.h>
#include <opencv2/opencv.hpp>
#include "dlib/image_processing.h"
#include "dlib/gui_widgets.h"
#include "dlib/image_io.h"
#include "dlib/dir_nav.h"
#include <dlib/opencv/cv_image.h>
using namespace cv;
using namespace dlib;
using namespace std;
int main(int argc, char * argv[]){
VideoCapture cap(0);
Mat frame;
while (cap.read(frame)) {
cvtColor(frame, frame, CV_RGB2GRAY);
cv_image<unsigned char> img(frame);
correlation_tracker tracker;
tracker.start_track(img, centered_rect(point(120,100), 80, 150));
image_window win;
tracker.update(img);
win.set_image(img);
win.clear_overlay();
win.add_overlay(tracker.get_position());
cout << "hit enter to process next frame" << endl;
cv::waitKey(0);
}
}
and with an uglier opencv 2..
#include <stdio.h>
#include <opencv2/opencv.hpp>
#include "dlib/image_processing.h"
#include "dlib/gui_widgets.h"
#include "dlib/image_io.h"
#include "dlib/dir_nav.h"
#include <dlib/opencv/cv_image.h>
using namespace cv;
using namespace dlib;
using namespace std;
int main(int argc, char * argv[]){
CvCapture* camera = cvCaptureFromFile(argv[1]);
if (camera==NULL)
printf("camera is null\n");
else
printf("camera is not null\n");
cvNamedWindow("CvCapture");
while (cvWaitKey(1000)!=atoi("q")) {
double t1 = (double)cvGetTickCount();
IplImage *img = cvQueryFrame(camera);
cvSetImageROI(img, cvRect(140, 150, 340, 150));
IplImage *img1 = cvCreateImage(cvGetSize(img), img->depth, img->nChannels);
cvCopy(img, img1, NULL);
cvResetImageROI(img);
cvShowImage("ROI",img1);
cvCvtColor(img1, img1, CV_RGB2GRAY);
cv_image<unsigned char> img2(img1);
correlation_tracker tracker;
tracker.start_track(img2, centered_rect(point(120,100), 80, 150));
image_window win;
tracker.update(img2);
win.set_image(img2);
win.clear_overlay();
win.add_overlay(tracker.get_position());
cout << "hit enter to process next frame" << endl;
cin.get();
double t2=(double)cvGetTickCount();
printf("time: %gms fps: %.2g\n",(t2-t1)/(cvGetTickFrequency()*1000.), 1000./((t2-t1)/(cvGetTickFrequency()*1000.)));
cvShowImage("CvCapture",img1);
}
cvReleaseCapture(&camera);
}
As you see the error came exactly from what I told you before.

OpenCV / HighGUI draws new windows for each attached object

I'm working through Learning OpenCV 3 by Kaehler & Bradski.
I've applied all errata fixes to this code per http://www.oreilly.com/catalog/errata.csp?isbn=0636920044765.
Expected behavior: the trackbar should be attached to the namedWindow "Example2-4", then frames from a video file (specified via command-line argument) should be drawn in the same window.
Actual behavior: the trackbar is drawn in one window named "Example2-4", then the frames are drawn in a second window named "Example2-4". Closing either window causes the program to hang. Otherwise the behavior is correct.
Platform: Windows 10, x64, OpenCV 3.3
Edit 1:
I tried adding a string literal to the top of main():
char *window_name = "Window";
and replacing every instance of "Example2-4" with window_name. This didn't change the behavior.
Edit 2:
This code is the first time I've tried to add an interactive widget, but adding images and video frames to windows in previous examples also generated two windows with the same name. I suspect I'm up against a configuration issue, but I still have no idea how to solve it.
Edit 3: I've added code for the simplest program that will demonstrate the problem behavior, and changed the title of this post to characterize it better.
Code:
/* Windows precompiled headers */
//#include "stdafx.h"
/* C++ */
#include <iostream>
#include <fstream>
/* OpenCv */
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace std;
int g_slider_position = 0;
int g_run = 1, g_dontset = 0; // start out in single step mode
cv::VideoCapture g_cap;
void onTrackBarSlide(int pos, void *);
int main(int argc, char **argv)
{
cv::namedWindow("Example2-4", CV_WINDOW_AUTOSIZE);
g_cap.open(string(argv[1]));
int frames = (int)g_cap.get(CV_CAP_PROP_FRAME_COUNT);
int tmpw = (int)g_cap.get(CV_CAP_PROP_FRAME_WIDTH);
int tmph = (int)g_cap.get(CV_CAP_PROP_FRAME_HEIGHT);
cout << "Video has " << frames << " frames of dimensions ("
<< tmpw << ", " << tmph << ")." << endl;
cv::createTrackbar("Position", "Example2-4", &g_slider_position, frames,
onTrackBarSlide);
cv::Mat frame;
for (;;) {
if (g_run != 0) {
g_cap >> frame;
if (frame.empty())
break;
int current_pos = (int)g_cap.get(CV_CAP_PROP_POS_FRAMES);
g_dontset = 1;
cv::setTrackbarPos("Position", "Example2-4", current_pos);
cv::imshow("Example2-4", frame);
g_run -= 1;
}
char c = (char)cv::waitKey(10);
if (c == 's') { // single step
g_run = 1;
cout << "Single step, run = " << g_run << endl;
}
if (c == 'r') { // run mode
g_run = -1;
cout << "Run mode, run = " << g_run << endl;
}
if (c == 27)
break;
}
return 0;
}
void onTrackBarSlide(int pos, void *) {
g_cap.set(CV_CAP_PROP_POS_FRAMES, pos);
if (!g_dontset)
g_run = 1;
g_dontset = 0;
}
Simplest code which results in problem behavior. Gets an image via command line argument:
#include <opencv2\opencv.hpp>
int main(int argc, char **argv)
{
char *window_name = "Window";
cv::Mat img = cv::imread(argv[1], -1);
if (img.empty())
return -1;
cv::namedWindow(window_name, CV_WINDOW_AUTOSIZE);
cv::imshow(window_name, img);
cv::waitKey(0);
cv::destroyWindow(window_name);
return 0;
}

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