show first frame in the video using open cv? - visual-c++

I am working on stereo vision.Here i have two stereo videos.I wanted to do following things
1]extract the first frame from the video .
2] convert the frame to gray channel(so that i can apply SURF features)
3]display the first frame (getting error in the code given below)
4]store the video with small size(currently it is 1600*1200)
can anyone give suggestion how to do?
my code is given below(written in c++)
#include <stdio.h>
#include <iostream>
#include <vector>
#include <time.h>
#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include "opencv2\features2d\features2d.hpp"
#include "opencv2\nonfree\features2d.hpp"
#include "opencv2\nonfree\nonfree.hpp"
#include "opencv2\flann\flann.hpp"
#include "opencv2\contrib\contrib.hpp"
#include <opencv2\calib3d\calib3d.hpp>
#include <opencv2\gpu\gpumat.hpp>
#pragma comment (lib, "opencv_core243d")
#pragma comment (lib, "opencv_highgui243d")
#pragma comment (lib, "opencv_imgproc243d")
#pragma comment (lib, "opencv_features2d243d")
#pragma comment (lib, "opencv_nonfree243d")
#pragma comment (lib, "opencv_flann243d")
#pragma comment (lib, "opencv_contrib243d")
#pragma comment (lib, "opencv_calib3d243d")
#pragma comment (lib, "opencv_gpu243d")
using namespace std;
using namespace cv;
int main(int argc, char**argv)
{
clock_t start_time=clock();
long lframecount=0;
//load the videos
VideoCapture capture1(argv[1]);
VideoCapture capture2(argv[2]);
cout << argv[1] << endl;
cout << argv[2] << endl;
if(!capture1.isOpened()||!capture2.isOpened())
{
cout<<"cant load stereo video";
return -1;
}
Mat frame1,frame2;
capture1>>frame1;
capture2>>frame2;
int num_rows=frame1.rows;
int num_cols=frame1.cols;
std::cout<<"number of rows and colums"<<num_rows<<":"<<num_cols<<std::endl;
int output_rows=num_rows/4;
int output_cols=num_cols/4;
long framecount1= capture1.get(CV_CAP_PROP_FRAME_COUNT);
long framecount2= capture2.get(CV_CAP_PROP_FRAME_COUNT);
VideoWriter write;
write.open("E:\\Vipil\\open_cv_learning\\video\\new22.avi",CV_FOURCC('D','I','V','X'), 30,cv::Size(output_rows,output_cols) ,true);
if (!write.isOpened())
{
std::cout << "cant open output video";
return -1;
}
namedWindow("depthmap",cv::WINDOW_NORMAL);
cv::Point tex(570, 50);
cv::Mat image1;
cv::Mat image2;
for(long i=1;i<6;i++)
{
lframecount++;
int number=lframecount;
string frame;
std::ostringstream convert;
convert<<number;
frame = convert.str();
capture1>> frame1;
capture2>> frame2;
cv::cvtColor(frame1,image1,CV_RGB2GRAY);
cv::cvtColor(frame2,image2,CV_RGB2GRAY);
imshow("image1",frame1);
//cout<<lframecount<<"\n";
}

You will need to use waitKey(30) or some delay to display image correctly.
Also to resize your frame you can simply use OpenCV resize() function.
Here is the reference
http://docs.opencv.org/modules/imgproc/doc/geometric_transformations.html

Related

bus error with mmap

I get bus error (core dumped) when trying to write to memory. I want to write to a binary file using mmap() and open() functions in Linux. I want to write integers from 1 to 100 in the binary file by mapping it to memory instead of writing to the file directly.
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/mman.h>
#include <string.h>
#include <stdlib.h>
#define FILE_SIZE 0x100
int main(int argc,char *argv[])
{
int fd;
void *pmap;
printf("im here");
//fd=open(argv[1],O_RDWR|O_CREAT,S_IRUSR|S_IWUSR);
fd=open("numbers.raw",O_RDWR);
if(fd == -1)
{
perror("open");
exit(1);
}
lseek(fd,FILE_SIZE+1,SEEK_SET); //checking the file length
lseek(fd,0,SEEK_SET);//points to start of the file
//create the memory mapping
pmap = mmap(0,FILE_SIZE,PROT_WRITE,MAP_SHARED,fd,0);
if(pmap == MAP_FAILED)
{
perror("mmap") ;
close(fd);
exit(1);
}
close(fd);
for(int i=1;i<=100;i++)
sprintf(pmap,"%d",i);
return 0;
}
Your comment says you are "checking the file length" but you never check the return value of that call. I'd bet it is failing since your file is not large enough, hence the bus error later.
There are multiple other unrelated mistakes in your file as well, by
the way:
Your file size assumes 0x100 bytes are enough to store 100 integers in binary. This is not the case for 64 bit systems.
You aren't actually storing binary numbers - you are storing strings of the numbers.
You aren't advancing where you write, so you write all the numbers at the start of the file, one on top of the other.

Listing the Files in a Directory in Visual C++

I have tried to "simplify" a nice piece of example code, the hyperlink to the code is at the end of this message, to specify the directory string instead of passing it as a command line argument. The simplified code compiles and executes, but the filename and size are not what I expect: the file name appears to be a hex number, and the nFileSize.High is larger than the nFileSize.Low (the actual file sizes range from 0 to 100Mb). I think my type casting may have introduced errors. Any suggestions?
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
#include <cctype>
#include <bitset>
#include <sstream>
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <strsafe.h>
#pragma comment(lib, "User32.lib")
using namespace std;
using namespace System; //set common language runtime support to /clr
int main()
{
WIN32_FIND_DATA ffd;
LARGE_INTEGER filesize;
//TCHAR szDir[MAX_PATH];
//size_t length_of_arg;
HANDLE hFind = INVALID_HANDLE_VALUE;
//DWORD dwError=0;
finstr = "C:\\Users\\MyName\\Documents\\Visual Studio 2010\\Projects\\Data Analysis\\Data Folder\\*";
//Just evaluate the first file before looping over all files
hFind = FindFirstFile((wchar_t*)(finstr.c_str()), &ffd);
wstring wsfname(ffd.cFileName);
string newtemp(wsfname.begin(), wsfname.end());
cout << "1st fname = " << ffd.cFileName << " newtemp = "<< newtemp << " nFSizeLo = "<< ffd.nFileSizeLow << " nFSizeHi = "<< ffd.nFileSizeHigh << "\n";
FindClose(hFind);
return 0;
}
Link to original example from Microsoft
https://msdn.microsoft.com/en-us/library/windows/desktop/aa365200(d=printer,v=vs.85).aspx

SDL2 Threads C++ pointer corruption

So, i have the following problem which may seem pretty strange or too elementary. This code snippet demonstrates my problem.
#ifdef __cplusplus
#include <cstdlib>
#else
#include <stdlib.h>
#endif
#include "SDL2/SDL.h"
#include <iostream>
using namespace std;
int doSTH(void* data){
int* data2 = (int*)data;
cout << data2 << endl;
return 0;
}
int main(){
SDL_Init(SDL_INIT_EVERYTHING);
int* data = new int(2);
cout << data << endl;
SDL_CreateThread(doSTH, "sth", (void*)data);
SDL_Delay(1);
delete data;
SDL_Quit();
}
Output is
0x2479f40
0x400c05
That means that somehow the function i call doesn't get the pointer i give it, am i missing something?
I am using Linux Ubuntu 14.04, g++ 4.8 and codeblocks.
Please tell me if i should give any more info.
Thanks in advance.
Nevermind, somehow the build of SDL2 was screwed up. I just uninstalled libx11-dev, rebooted and then reinstalled libsdl2-dev and now it works correctly.

How to calculate the intersection of a line segment and circle with CGAL

I've been banging my head against a wall trying to understand how to use CGAL's Circular Kernel to calculate the intersection(s) between a line segment (Line_Arc_2) and a Circle (Circle_2). Unfortunately there isn't much in the way of example code for the Circular Kernel, and I'm not finding the reference manual much help.
Here is code that I thought would work, but right now it won't even compile (Mac OS 10.9 using the latest system compiler):
#include <vector>
#include <iterator>
#include <CGAL/Exact_circular_kernel_2.h>
#include <CGAL/Circular_kernel_intersections.h>
#include <CGAL/intersections.h>
#include <CGAL/result_of.h>
#include <CGAL/iterator.h>
#include <CGAL/point_generators_2.h>
#include <boost/bind.hpp>
typedef CGAL::Exact_circular_kernel_2 CircK;
typedef CGAL::Point_2<CircK> Pt2;
typedef CGAL::Circle_2<CircK> Circ2;
typedef CGAL::Line_arc_2<CircK> LineArc2;
typedef CGAL::cpp11::result_of<CircK::Intersect_2(Circ2,LineArc2)>::type Res;
int main(){
int n = 0;
Circ2 c = Circ2(Pt2(1,0), Pt2(0,1), Pt2(-1, 0));
LineArc2 l = LineArc2( Pt2(0,-2), Pt2(0,2) );
std::vector<Res> result;
CGAL::intersection(c, l, std::back_inserter(result));
return 0;
}
I get an error on the result_of line: "error: no type named 'result_type' in...", and a second error that "no viable overloaded '='" is available for the intersection line.
Also, since this would probably be the follow up question once this is working: how do I actually get at the intersection points that are put in the vector? CGAL's documentation suggests to me "result" should contain pairs of a Circular_arc_point_2 and an unsigned int representing its multiplicity. Is this what I will actually get in this case? More generally, does anyone know a good tutorial for using the Circular Kernel and Spherical Kernel intersection routines?
Thanks!
So it seems that result_of doesn't work here, despite being suggested in the CGAL reference manual for the CircularKernel's intersection function.
Here is a different version that seems to work and can properly handle the output:
#include <vector>
#include <iterator>
#include <CGAL/Exact_circular_kernel_2.h>
#include <CGAL/Circular_kernel_intersections.h>
#include <CGAL/intersections.h>
#include <CGAL/iterator.h>
typedef CGAL::Exact_circular_kernel_2 CircK;
typedef CGAL::Point_2<CircK> Pt2;
typedef CGAL::Circle_2<CircK> Circ2;
typedef CGAL::Line_arc_2<CircK> LineArc2;
typedef std::pair<CGAL::Circular_arc_point_2<CircK>, unsigned> IsectOutput;
using namespace std;
int main(){
int n = 0;
Circ2 c = Circ2(Pt2(1.0,0.0), Pt2(0.0,1.0), Pt2(-1.0, 0.0));
LineArc2 l = LineArc2( Pt2(0.0,-2.0), Pt2(0.0,2.0) );
std::vector<IsectOutput> output;
typedef CGAL::Dispatch_output_iterator< CGAL::cpp11::tuple<IsectOutput>,
CGAL::cpp0x::tuple< std::back_insert_iterator<std::vector<IsectOutput> > > > Dispatcher;
Dispatcher disp = CGAL::dispatch_output<IsectOutput>( std::back_inserter(output) );
CGAL::intersection(l, c, disp);
cout << output.size() << endl;
for( const auto& v : output ){
cout << "Point: (" << CGAL::to_double( v.first.x() ) << ", " << CGAL::to_double( v.first.y() ) << "), Mult: "
<< v.second << std::endl;
}
return 0;
}
result_of is working but the operator you are asking for does not exist, you are missing the output iterator.
However, I agree the doc is misleading. I'll try to fix it.
The following code is working fine:
#include <vector>
#include <iterator>
#include <CGAL/Exact_circular_kernel_2.h>
#include <CGAL/Circular_kernel_intersections.h>
#include <CGAL/intersections.h>
#include <CGAL/result_of.h>
#include <CGAL/iterator.h>
#include <CGAL/point_generators_2.h>
#include <boost/bind.hpp>
typedef CGAL::Exact_circular_kernel_2 CircK;
typedef CGAL::Point_2<CircK> Pt2;
typedef CGAL::Circle_2<CircK> Circ2;
typedef CGAL::Line_arc_2<CircK> LineArc2;
typedef boost::variant<std::pair<CGAL::Circular_arc_point_2<CircK>, unsigned> > InterRes;
typedef CGAL::cpp11::result_of<CircK::Intersect_2(Circ2,LineArc2,std::back_insert_iterator<std::vector<InterRes> >)>::type Res;
int main(){
Circ2 c = Circ2(Pt2(1,0), Pt2(0,1), Pt2(-1, 0));
LineArc2 l = LineArc2( Pt2(0,-2), Pt2(0,2) );
std::vector<InterRes> result;
CGAL::intersection(c, l, std::back_inserter(result));
return 0;
}

Bus error opening and mmap'ing a file

I want to create a file and map it into memory. I think that my code will work but when I run it I'm getting a "bus error". I searched google but I'm not sure how to fix the problem. Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/mman.h>
#include <string.h>
int main(void)
{
int file_fd,page_size;
char buffer[10]="perfect";
char *map;
file_fd=open("/tmp/test.txt",O_RDWR | O_CREAT | O_TRUNC ,(mode_t)0600);
if(file_fd == -1)
{
perror("open");
return 2;
}
page_size = getpagesize();
map = mmap(0,page_size,PROT_READ | PROT_WRITE,MAP_SHARED,file_fd,page_size);
if(map == MAP_FAILED)
{
perror("mmap");
return 3;
}
strcpy(map, buffer);
munmap(map, page_size);
close(file_fd);
return 0;
}
You are creating a new zero sized file, you can't extend the file size with mmap. You'll get a bus error when you try to write outside the content of the file.
Use e.g. fallocate() on the file descriptor to allocate room in the file.
Note that you're also passing the page_size as the offset to mmap, which doesn't seem to make much sense in your example, you'll have to first extend the file to pagesize + strlen(buffer) + 1 if you want to write buf at that location. More likely you want to start at the beginning of the file, so pass 0 as the last argument to mmap.

Resources