I'am actually trying to extract images from a gifFile using the giflib with the following code.
t_gif initGif(const char *filename){
t_gif gif;
int *error;
GifFileType *GifFile = DGifOpenFileName(filename, error);
assert(error != NULL);
int ret = DGifSlurp(GifFile);
assert(ret == GIF_OK);
gif.h = (int)GifFile->SHeight;
gif.w = GifFile->SWidth;
gif.nbFrames = GifFile->ImageCount;
gif.colorSize = GifFile->SColorResolution;
GifImageDesc Image = GifFile->Image;
SavedImage *img = &GifFile->SavedImages[0];
cout << "width: " << gif.w << endl;
cout << "height: " << gif.h << endl;
cout << "Image Count: " << gif.nbFrames << endl;
cout << "SColor Resolution: " << gif.colorSize << endl;
Mat color = Mat(Size(gif.w, gif.h), CV_8UC1, img->RasterBits);
imwrite("./test.png", color);
return gif;
}
But this causes a segfault. I am using opencv in v2.4.5 and giflib in v5.0.4.
I think this is not caused by Opencv because with giflib in v4 I had no problem here.
MoreOver the following test also causes segfault.
printf("%u\n", (unsigned int)img->RasterBits[0]);
Gdb output:
(gdb) run bsd.gif
Starting program: /home/matt/Code/perso/utils/gif/a.out bsd.gif
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Gif Analyser tool
started by MG in may 2013
compiled with giflib: v5.0.4
width: 1000
height: 907
Image Count: 0
SColor Resolution: 8
Program received signal SIGSEGV, Segmentation fault.
0x0000000000401af3 in initGif (filename=0x7fffffffe2be "bsd.gif") at main.cpp:40
40 Mat color = Mat(Size(gif.w, gif.h), CV_8UC1, img->RasterBits);
(gdb)
I also don't find how to get color back using the colorGlobal table.
Can someone Help me ?
Thanks
I just get back to version 4.1.6 and everything is good. The v5 is probably bugged.
To get the color information , you can use the rasterbits of the image as index to the colormap hence getting the RGB information for the corresponding pixel.Then you can simply use CV_8UC3 data type for storing the gif frame as a colored png .
Related
I try to read in a gpkg file to extract geo informations like streets and buildings.
Therefor I started with this code:
#include "gdal_priv.h"
#include <iostream>
int main() {
GDALDataset* poDataset;
GDALAllRegister();
std::cout << "driver# " << GetGDALDriverManager()->GetDriverCount()
<< std::endl;
for (int i = 0; i < GetGDALDriverManager()->GetDriverCount(); i++) {
auto driver = GetGDALDriverManager()->GetDriver(i);
auto info = driver->GetDescription();
std::cout << "driver " << i << ": " << info << std::endl;
}
auto driver = GetGDALDriverManager()->GetDriverByName("GPKG");
poDataset = (GDALDataset*)GDALOpen("Building_LoD1.gpkg", GA_ReadOnly);
if (poDataset == NULL) {
// ...;
}
return 0;
}
The driver list contains GPKG, but the reading fails with an error that the file is not recognized as supported file format.
Doing a gdalinfo Building_LoD1.gpkg leads to the same error in the console. But I can open the file in QGIS.
And a gdalsrsinfo Building_LoD1.gpk reports:
PROJ.4 : +proj=somerc +lat_0=46.95240555555556 +lon_0=7.439583333333333 +k_0=1 +x_0=2600000 +y_0=1200000 +ellps=bessel +towgs84=674.374,15.056,405.346,0,0,0,0 +units=m +no_defs
OGC WKT :
PROJCS["CH1903+ / LV95",
GEOGCS["CH1903+",
DATUM["CH1903+",
SPHEROID["Bessel 1841",6377397.155,299.1528128,
AUTHORITY["EPSG","7004"]],
TOWGS84[674.374,15.056,405.346,0,0,0,0],
AUTHORITY["EPSG","6150"]],
PRIMEM["Greenwich",0,
AUTHORITY["EPSG","8901"]],
UNIT["degree",0.0174532925199433,
AUTHORITY["EPSG","9122"]],
AUTHORITY["EPSG","4150"]],
PROJECTION["Hotine_Oblique_Mercator_Azimuth_Center"],
PARAMETER["latitude_of_center",46.95240555555556],
PARAMETER["longitude_of_center",7.439583333333333],
PARAMETER["azimuth",90],
PARAMETER["rectified_grid_angle",90],
PARAMETER["scale_factor",1],
PARAMETER["false_easting",2600000],
PARAMETER["false_northing",1200000],
UNIT["metre",1,
AUTHORITY["EPSG","9001"]],
AXIS["Easting",EAST],
AXIS["Northing",NORTH],
AUTHORITY["EPSG","2056"]]
Does anyone know why a gpkg file might be reported as not supported?
The gdal version is 2.3.2.
I figured out the problem. The reason for the message is not that the file format is not support by gdal, but that I used the wrong function to open the file.
If I want to read in a file that has vector information then I need to use:
GDALDataset* poDS;
poDS = (GDALDataset*)GDALOpenEx( "Building_LoD1.gpkg", GDAL_OF_VECTOR, NULL, NULL, NULL);
I'm now working on feature matching, and I wrote these codes below.
void CLPS::ExtractKeyPoints()
{
vector<DMatch> init_matches;
ULONGLONG timer;
timer = GetTickCount64();
Ptr<BRISK> fd_a = BRISK::create(20);
fd_a->detectAndCompute(S, Mat(), spoints, desc_s, false);
fd_a->detectAndCompute(T, Mat(), tpoints, desc_t, false);
timer = GetTickCount64() - timer;
cout << "Detect and compute: " << timer << " milliseconds complete. Output: " << spoints.size() << " points. \n";
timer = GetTickCount64();
FlannBasedMatcher matcher = FlannBasedMatcher(cv::makePtr<cv::flann::LshIndexParams>(10, 32, 2));
matcher.match(desc_s, desc_t, init_matches);
timer = GetTickCount64() - timer;
cout << "Matching time: " << timer << " milliseconds complete. " << endl;
Point2f spt, tpt;
int num_matches = 0;
vector<DMatch>::iterator iter_matches;
coord_matches.create(1, 3, CV_32FC1);
Mat cm_row;
cm_row.create(1, 3, CV_32FC1);
if (!init_matches.empty())
{
for (iter_matches = init_matches.begin(); iter_matches != init_matches.end(); ++iter_matches)
{
spt = spoints[iter_matches->queryIdx].pt;
tpt = tpoints[iter_matches->trainIdx].pt;
if (std::abs(spt.y - tpt.y) < VERTICAL_EPSILON && tpt.x - spt.x < upperbound && tpt.x - spt.x > lowerbound)
{
num_matches++;
coord_matches.reserve(num_matches);
cm_row.at<float>(0, 0) = spt.x;// 与 CV_32FC1 对应
cm_row.at<float>(0, 1) = spt.y;
cm_row.at<float>(0, 2) = tpt.x - spt.x;
coord_matches.push_back(cm_row);
}
}
cout << coord_matches.rows << " matches found." << endl;
}
else
{
cerr << "No match is found. Validate your source data or report to us if there is a bug. " << endl;
}
}
Then I just call it like this:
CLPS lps;
lps.ExtractKeyPoints();
However, it triggers an exception with following message when this function is returning:
Unhandled exception at 0x00007FFC0797D328 (ucrtbase.dll) in dars_lps.exe: An invalid parameter was passed to a function that considers invalid parameters fatal.
where dars_lps.exe is my application name. Then the program jumps to some destructors in <vector>.
I'm using Visual Studio 2015 on Windows 8.1 Update 1, and my OpenCV version is 3.1. I have confirmed that I'm linking to correct version of library files (i.e. vc14).
I was once working on Visual Studio 2010 on Windows 7 SP1, OpenCV 2.4.9, but it never reported such an exception.
I know this question may be similar to some other questions elsewhere (e.g. this on OpenCV site), occuring when calling different functions, but all of them are staying unsolved. I suspect that the problem lies in BRISK or FlannBasedMatcher, but I can't comment out those code (or this function will be virtually empty, and obviously, no more exceptions).
I also noticed that the problem was rising up after OpenCV 3.0 was released, and most of the similar problems happen in newer versions of Visual Studio or Windows. Both 64-bit and 32-bit platforms have this kind of problems. There does exist a report of such problem in Visual Studio 2015 here, but it was OpenCV 3.0 that is used, when there were no library built for Visual Studio 2015 yet.
Is it still a bug to be fixed or an error of syntax by myself?
I have application made with QTCreator. It uses OpenCV 2.4.11. I have the same application on Visual. Code is the same in both.
OpenCV for Microsoft Visual 2013 was made using this link:
https://www.youtube.com/watch?v=e_TQ9c3n_d8
It is for 2.4.10, but it's the same for 2.4.11.
And I configured QtCreator with this tutorial:
How to link opencv in QtCreator and use Qt library
Now the code:
#include <opencv2\highgui\highgui.hpp>
#include <iostream>
#include <fstream>
#include <opencv2\highgui\highgui.hpp>
#include "opencv2\stitching\stitcher.hpp"
using namespace cv;
using namespace std;
void ReadPhotos();
double begin_t, end_t;
int photo_number = 0;
Mat photos[100];
Mat image;
vector< Mat > ImagesVector;
vector<Mat> roisVector;
int main()
{
cout << "Starting program!" << endl;
ReadPhotos();
Size size(1050, 600);
for (int i = 0; i < photo_number; i++){
//resize(photos[i], photos[i], size);
ImagesVector.push_back(photos[i]);
}
Stitcher stitcher = Stitcher::createDefault(true);
stitcher.setWarper(new SphericalWarper());
stitcher.setFeaturesFinder(new detail::SurfFeaturesFinder(300, 3, 4, 3, 4));
stitcher.setRegistrationResol(0.9);
stitcher.setSeamEstimationResol(0.9);
stitcher.setCompositingResol(1);
stitcher.setPanoConfidenceThresh(1);
stitcher.setWaveCorrection(true);
stitcher.setWaveCorrectKind(detail::WAVE_CORRECT_HORIZ);
stitcher.setFeaturesMatcher(new detail::BestOf2NearestMatcher(false, 0.3));
stitcher.setBundleAdjuster(new detail::BundleAdjusterRay());
Stitcher::Status status = Stitcher::ERR_NEED_MORE_IMGS;
try{
status = stitcher.stitch(ImagesVector, image);
}
catch (cv::Exception e){}
imwrite("panorama.jpg", image);
waitKey(0);
return 0;
}
void ReadPhotos(){
string sourceIN;
string sourcePhoto;
sourceIN = "paths1.txt";
ifstream FileIN(sourceIN);
if (FileIN.is_open())
{
while (getline(FileIN, sourcePhoto)){
photos[photo_number] = imread(sourcePhoto, 1);
photo_number++;
}
}
else{
cout << "Can't find file" << endl;
}
cout << "Number of photos: " << photo_number << endl;
}
Read photos function takes path to images from txt file and load photos.
In visual studio it's working good, I can stitch 3500x2000 resulution images and it gives nice output panorama. In QtCreator I try to stitch the same images and it gives following errors:
OpenCV Error: Insufficient memory (Failed to allocate 290519044 bytes) in OutOfMemoryError, file C:\OpenCV2411\opencv\sources\modules\core\src\alloc.cpp, line 52
terminate called after throwing an instance of 'cv::Exception'
what(): C:\OpenCV2411\opencv\sources\modules\core\src\alloc.cpp:52: error: (-4) Failed to allocate 290519044 bytes in function OutOfMemoryError
Bad alloc - sorry, I can't make this error again so can't copy exactly.
Anyone has any idea why the same code is not working on QTCreator and is working in Visual Studio 2013? Library is the same. One thing I can think of is that I build libraries for QTCreator myself with Cmake. Maybe it has something with this.
Ive been stuck with this problem for a few days and I thought I'd ask for help.
I have written this test code to display my issue
this is my take picture function
cv::Mat takePicture(){
cv::Mat pic;
VideoCapture cam(0);
if(!cam.isOpened()){
std::cout << "Failed to make connection to Cam" << std::endl;
exit(1);
}
cam.set(CV_CAP_PROP_FRAME_WIDTH, 320);
cam.set(CV_CAP_PROP_FRAME_HEIGHT, 240);
cam >> pic;
cvWaitKey(100);
return pic.clone();
}
this is a loop in my main function that will cause a crash
if(test_mode == true){
while(true){
Mat testImg;
char fileName[50];
sprintf(fileName, "testFile%d", threadNo);
testImg = takePicture();
cout << "current pic is " << threadNo << endl;
threadNo++;
testImg.release();
}
}
The program will run fine until image 27 it will then go slower and by image 30 I will get a variety of errors they are
mmap: Cannot allocate memory
munmap: Invalid argument
Unable to stop the stream.: Bad file descriptor
libv4l1: error allocating v4l1 buffers: Cannot allocate memory
HIGHGUI ERROR: V4L: Mapping Memmory from video source error: Invalid argument
HIGHGUI ERROR: V4L: Initial Capture Error: Unable to load initial memory buffers
*** glibc detected *** ./Cam: free(): invalid pointer: 0x0076ab88 ***
Aborted
I keep thinking this must be caused by a leak. Thanks in advance for the help.
I am developing an application that requires multiple webcams. In order to make sure that the correct webcam is used for each part of the application, I created some udev rules that SYMLINK the webcam to a specific name, depending on the serial number.
This works great, and I can access the camera by that name using VLC and a variety of other applications.
But when I try to access the camera by that name (or the non-syminked name given by linux) using OpenCV and python, I can't read a frame from the camera and my program hangs. The camera is opened successfully. I've created a sample application in C++ to test if it was perhaps a python/opencv related bug, but the same thing happens in C++ too.
Here is my C++ test application that doesn't work:
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main (int argc, const char * argv[])
{
VideoCapture cap("/dev/my_custom_name");
if (!cap.isOpened())
return -1;
cout << "Opened..." << endl;
Mat img;
namedWindow("video capture", CV_WINDOW_AUTOSIZE);
while (true)
{
cout << "Trying..." << endl;
cap >> img;
cout << "Got" << endl;
imshow("video capture", img);
if (waitKey(10) >= 0)
break;
}
return 0;
}
I get the Opened... and Trying... messages, but not the Got message.
Any ideas on how to resolve this issue?
(This is all on linux btw).
Thanks
I figured this out. When I opened the capture in VLC, I noticed that it preixed the filename with v4l2://. When I did the same in my application, it worked!
So to reference above, "/dev/my_custom_name" should become "v4l2:///dev/my_custom_name".