C++, OpenCV : Assertion failed in Resize - c++

As a C++ beginner, I am currently facing a problem I somehow can't solve, even if the code is pretty simple.
I've been searching for answers all over the Internet, but none was applicable for my problem.
I am currently coding basic SVMs with C++, under VS2013, using OpenCV 2.4.8.
I was able to work on images of same size, specifying fixed height, width at the beginning of my code.
Now, I'm trying to : open images of different sizes, resize them to a certain lower size, and apply the previous code to the now-resized dataset. Simple as that.
Here's the beginning of my code :
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/ml/ml.hpp>
#include <iostream>
#include <math.h>
#include <fstream>
#include <string>
#include <sstream>
#include <windows.h>
using namespace cv;
using namespace std;
int main(){
Input parameters are :
int Nb_Data_Class_1 = 10;
int Nb_Data_Class_0 = 5;
int Height_Zone = 200;
int Width_Zone = 200;
so I will resize all my files to 200x200 format.
string Path = "C:\\Users\\....";
string Format = ".jpg";
int Nb_Files = Nb_Data_Class_1 + Nb_Data_Class_0;
Mat TrainingMat(Nb_Files, Zone_Image, CV_32FC1);
Mat TrainingLabels(Nb_Files, 1, CV_32FC1);
For every file of the class labelled {1} - they are all named Tree01, Tree02, etc. - I open, and resize.
for (int i = 0; i < Nb_Data_Class_1; ++i)
{
stringstream ss;
ss << Path << "\\Tree0" << i + 1 << Format;
Mat Image = cv::imread(ss.str(), 0);
resize(Image, Image, Size(Width_Zone, Height_Zone));}
Things worked perfectly without the last line. I had a Mat array, filled with 0-t0-255 numbers. Now, I get the following error :
OpenCV Error: Assertion failed <ssize.area<> >0> in cv::resize,
file C:\builds\2-4-PackSlave-win32-vc12-shared\opencv\modules\imgproc\serc\imgwarp.cpp, line 1824
What could be the problem ?
I thought that maybe OpenCV wasn't properly opening the files ; but, in that case, how everything could have been previously working ?
Still wondering.
Any help would be much appreciated ! Thanks in advance.

The only reason for resize to crush is absence of Image. Even if you checked that some of the images were read properly it doesn't mean that all of them were - some of them may be missing. Reading files from disk is a very common point of failure for programs because you never can be sure if the read was successfully or not. As a result every time you read an image you really really should verify that it is not empty:
if (Image.cols == 0) {
cout << "Error reading file " << ss << endl;
return -1;
}

Not going to solve the problem in this case, but this assertion can also be caused by trying to resize a Mat with a signed type like CV_8SC3. For example:
Mat wrong = Mat::zeros(4, 4, CV_8SC3); // <- Notice 'S'
Mat right = Mat::zeros(4, 4, CV_8UC3); // <- Notice 'U'
imshow("OK", right);
imshow("ASSERTS", wrong);
Note that checking wrong.cols != 0 will not prevent this from crashing.

Your line:
ss << Path << "\Tree0" << i + 1 << Format;
will produce (where i=0):
"C:\Users\....\Tree01.jpg".
Solution
Change "string Path = "C:\Users\....";" line to:
string Path = "C:\Users";
and
change "ss << Path << "\Tree0" << i + 1 << Format;" line to:
ss << Path << "Tree0" << i + 1 << Format;

Related

Reading step file with Open Cascade

I need to read simple step files (turning parts) with C++. Therefore I try to use Open Cascade. I already can open my step file and read the number of shapes in my file. Now I need to get the geometrical data (length, width, diameters..), but I dont know how it works, although I read all of the documentations.
Is there anyone who already worked with Open Cascade and can help me with my Problem? I would be very happy, thank alot !!
That's my Code since then
#include <iostream>
#include <STEPControl_Reader.hxx>
#include <string>
using namespace std;
int main() {
STEPControl_Reader reader;
IFSelect_ReturnStatus stat = reader.ReadFile("C:\\Users\\Kelevradesktop.Kelevra-desktop\\Desktop\\Studienarbeit\\steptest.step");
IFSelect_PrintCount mode = IFSelect_ListByItem;
reader.PrintCheckLoad(false, mode);
Standard_Integer NbRoots = reader.NbRootsForTransfer(); //Transfer whole file
Standard_Integer num = reader.TransferRoots();
Standard_Integer NbTrans = reader.TransferRoots();
TopoDS_Shape result = reader.OneShape();
TopoDS_Shape shape = reader.Shape();
cout << NbRoots << endl;
cout << NbTrans << endl;
cout << num << endl;
system("pause");
return 0;
}
Check the FreeCad source code. They use OpenCascade and can import step and iges. It should get you started. The function ImportStepParts(...) in https://github.com/FreeCAD/FreeCAD/blob/master/src/Mod/Part/App/ImportStep.cpp is what you search for.
Use TopExpExplorer class to iterate through the objects (vertexes, edges, faces..) of a shape. An iterating example you can find in this tutorial.
Use GProp_GProps class to get properties of a shape. Example:
GProp_GProps propertiesSystemFace;
BRepGProp::VolumeProperties(shape, propertiesSystemFace);
double shapeVolume = propertiesSystemFace.Mass();
gp_Pnt centerOfMass = propertiesSystemFace.CentreOfMass();
Also you can convert TopoDS_Edge to curve object to get some other parameters according to the edge type:
BRepAdaptor_Curve adaptCrv = BRepAdaptor_Curve(edge);

Why is the point-cloud-library's loadPCDFile so slow?

I am reading 2.2 million points from a PCD file, and loadPCDFile is using ca 13 sec both in Release as well as Debug mode. Given that visualization programs like CloudCompare can read the file in what seems like milliseconds, I expect that I am doing something harder than it needs to be.
What am I doing wrong?
The top of my PCD file:
# .PCD v0.7 - Point Cloud Data file format
VERSION 0.7
FIELDS rgb x y z _
SIZE 4 4 4 4 1
TYPE F F F F U
COUNT 1 1 1 1 4
WIDTH 2206753
HEIGHT 1
VIEWPOINT 0 0 0 1 0 0 0
POINTS 2206753
DATA binary
¥•ÃöèÝÃájfD ®§”ÃÍÌÝÃá:fD H”ø¾ÝÃH!fD .....
From my code, reading the file:
#include <iostream>
#include <vector>
#include <pcl/common/common.h>
#include <pcl/common/common_headers.h>
#include <pcl/common/angles.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/console/parse.h>
#include <pcl/filters/extract_indices.h>
#include <pcl/features/normal_3d.h>
#include <boost/thread/thread.hpp>
int main() {
(...)
pcl::PointCloud<pcl::PointXYZRGB>::Ptr largeCloud(new pcl::PointCloud<pcl::PointXYZRGB>);
largeCloud->points.resize(3000000); //Tried to force resizing only once. Did not help much.
if (pcl::io::loadPCDFile<pcl::PointXYZRGB>("MY_POINTS.pcd", *largeCloud) == -1) {
PCL_ERROR("Couldn't read file MY_POINTS.pcd\n");
return(-1);
}
(...)
return 0;
}
(Using PCL 1.8 and Visual Studio 2015)
Summary of below...
PCL is slightly slower at loading cloud compare formatted PCD files. Looking at the headers, CC seems to add an extra variable to each point "_" that PCL doesn't like and has to format out. But this is only a difference of 30%-40% load time.
Based on the result that with the same size point cloud (3M), my computer took 13 seconds to load it from cloud compare when the program was compiled in Debug mode and only 0.25s to load the same cloud in Release mode. I think that you are running in debug mode. Depending on how you compiled/installed PCL, you may need to rebuild PCL to generate the appropriate Release build. My guess is that whatever you think you are doing to change from Debug to Release is not in fact engaging the PCL release library.
In PCL, across almost all functions, moving from Debug to Release will often give you one to two orders of magnitude faster processing (due to PCL's heavy usage of large array objects that have to be managed differently in Debug mode for visibility)
Testing PCL with cloud compare files
Here is the code that I ran to produce the following outputs:
std::cout << "Press enter to load cloud compare sample" << std::endl;
std::cin.get();
TimeStamp stopWatch = TimeStamp();
pcl::PointCloud<pcl::PointXYZRGB>::Ptr tempCloud2(new pcl::PointCloud<pcl::PointXYZRGB>);
pcl::io::loadPCDFile("C:/SO/testTorusColor.pcd", *tempCloud2);
stopWatch.fullStamp(true);
std::cout <<"Points loaded: "<< tempCloud2->points.size() << std::endl;
std::cout << "Sample point: " << tempCloud2->points.at(0) << std::endl;
std::cout << std::endl;
std::cout << "Press enter to save cloud in pcl format " << std::endl;
std::cin.get();
pcl::io::savePCDFileBinary("C:/SO/testTorusColorPCLFormatted.pcd", *tempCloud2);
std::cout << "Press enter to load formatted cloud" << std::endl;
std::cin.get();
stopWatch = TimeStamp();
pcl::PointCloud<pcl::PointXYZRGB>::Ptr tempCloud3(new pcl::PointCloud<pcl::PointXYZRGB>);
pcl::io::loadPCDFile("C:/SO/testTorusColorPCLFormatted.pcd", *tempCloud3);
stopWatch.fullStamp(true);
std::cout << "Points loaded: " << tempCloud3->points.size() << std::endl;
std::cout << "Sample point: " << tempCloud3->points.at(0) << std::endl;
std::cout << std::endl;
std::cin.get();
Cloud compare generated colored cloud (3M points with color):
Running in Debug, reproduced your approximate load time with a 3M pt cloud:
Running in Release:
I was running into exactly this situation.
It simply comes down to file storage style. Your file (taking that long to load) is almost certainly an ASCII style point cloud file. If you want to be able to load it much faster (x100) then convert it to binary format. For reference, I load a 1M pt cloud in about a quarter second (but that is system dependent)
pcl::PointCloud<pcl::PointXYZ>::Ptr tempCloud(new pcl::PointCloud<pcl::PointXYZ>);
The load call is the same:
pcl::io::loadPCDFile(fp, *tempCloud);
but in order to save as binary use this:
pcl::io::savePCDFileBinary(fp, *tempCloud);
Just in case it helps, here is a snippet of the code I use to load and save clouds (I structure them a bit, but it is likely based on an example, so I don't know how important that is but you may want to play with it if you switch to binary and are still seeing long load times).
//save pt cloud
std::string filePath = getUserInput("Enter file name here");
int fileType = stoi(getUserInput("0: binary, 1:ascii"));
if (filePath.size() == 0)
printf("failed file save!\n");
else
{
pcl::PointCloud<pcl::PointXYZ> tempCloud;
copyPointCloud(*currentWorkingCloud, tempCloud);
tempCloud.width = currentWorkingCloud->points.size();
tempCloud.height = 1;
tempCloud.is_dense = false;
filePath = "../PointCloudFiles/" + filePath;
std::cout << "Cloud saved to:_" << filePath << std::endl;
if (fileType == 0){pcl::io::savePCDFileBinary(filePath, tempCloud);}
else
{pcl::io::savePCDFileASCII(filePath, tempCloud);}
}
//load pt cloud
std::string filePath = getUserInput("Enter file name here");
if (filePath.size() == 0)
printf("failed user input!\n");
else
{
filePath = "../PointCloudFiles/" + filePath;
pcl::PointCloud<pcl::PointXYZ>::Ptr tempCloud(new pcl::PointCloud<pcl::PointXYZ>);
if (pcl::io::loadPCDFile(filePath, *tempCloud) == -1) //* load the file
{
printf("failed file load!\n");
}
else
{
copyPointCloud(*tempCloud, *currentWorkingCloud); std::cout << "Cloud loaded from:_" << filePath << std::endl;
}
}
List item
This looks correct, when comparing with a pcl example. I think the main work of loadPCDFile is done in the function pcl::PCDReader::read, which is located in the file pcd_io.cpp. When checking the code for binary data, as it is in your case, there are 3 nested for loops which check if the numerical data of each field is valid. The exact code comment is
// Once copied, we need to go over each field and check if it has NaN/Inf values and assign cloud
That could be time consuming. However, I am speculating.

how to load jpeg file using DLIB libarary?

After attempting to run a example program downloaded from Here, I understand for working with jpeg files , I must add #define DLIB_JPEG_SUPPORT directive to the project. but before that It's necessary to download jpeg library and add it to the project. I did These steps:
1.Download jpegsr9a.zip from here and unzipped it.
2.Download WIN32.mak and paste it into the jpeg root folder
3.Open Developer Command Prompt from visual studio 2013 tools
4.In command prompt type : nmake -f makefile.vc setup-v10
5.After these steps jpeg.sln created ,the note is when I open jpeg.sln in VS2013 the message come:
maybe base of the problem start from here , I don't know
6.Build the jpeg.sln with the proper configuration (I built it many times with different configurations, recently I built it using this .)
at the end of building the error came :"unable to start jpeg.lib"
but in release folder or debug folder (depend on configuration) jpeg.lib was created
open main project which is using DLIB for detecting face,I added jpeg root folder to Additonal Include Directory and jepegroot/release to Additional Libarary Directories ,then change the UseLibrary dependencies to "yes" and I also added jpeg.lib to the dependecies.
during building the project errors come:
This is the source which I trying to build and run
//#define HAVE_BOOLEAN
#define DLIB_JPEG_SUPPORT
#include <dlib/image_processing/frontal_face_detector.h>
#include <dlib/image_processing/render_face_detections.h>
#include <dlib/image_processing.h>
#include<dlib/image_transforms.h>
#include <dlib/gui_widgets.h>
#include <dlib/image_io.h>
#include <iostream>
//
using namespace dlib;
using namespace std;
// ----------------------------------------------------------------------------------------
int main(int argc, char** argv)
{
try
{
// This example takes in a shape model file and then a list of images to
// process. We will take these filenames in as command line arguments.
// Dlib comes with example images in the examples/faces folder so give
// those as arguments to this program.
if (argc == 1)
{
cout << "Call this program like this:" << endl;
cout << "./face_landmark_detection_ex shape_predictor_68_face_landmarks.dat faces/*.jpg" << endl;
cout << "\nYou can get the shape_predictor_68_face_landmarks.dat file from:\n";
cout << "http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2" << endl;
return 0;
}
// We need a face detector. We will use this to get bounding boxes for
// each face in an image.
frontal_face_detector detector = get_frontal_face_detector();
// And we also need a shape_predictor. This is the tool that will predict face
// landmark positions given an image and face bounding box. Here we are just
// loading the model from the shape_predictor_68_face_landmarks.dat file you gave
// as a command line argument.
shape_predictor sp;
deserialize(argv[1])>>sp;
image_window win, win_faces;
// Loop over all the images provided on the command line.
for (int i = 2; i < argc; ++i)
{
cout << "processing image " << argv[i] << endl;
array2d<rgb_pixel> img;
load_image(img, argv[i]);
// Make the image larger so we can detect small faces.
pyramid_up(img);
// Now tell the face detector to give us a list of bounding boxes
// around all the faces in the image.
std::vector<rectangle> dets = detector(img);
cout << "Number of faces detected: " << dets.size() << endl;
// Now we will go ask the shape_predictor to tell us the pose of
// each face we detected.
std::vector<full_object_detection> shapes;
for (unsigned long j = 0; j < dets.size(); ++j)
{
full_object_detection shape = sp(img, dets[j]);
cout << "number of parts: " << shape.num_parts() << endl;
cout << "pixel position of first part: " << shape.part(0) << endl;
cout << "pixel position of second part: " << shape.part(1) << endl;
// You get the idea, you can get all the face part locations if
// you want them. Here we just store them in shapes so we can
// put them on the screen.
shapes.push_back(shape);
}
// Now let's view our face poses on the screen.
win.clear_overlay();
win.set_image(img);
win.add_overlay(render_face_detections(shapes));
// We can also extract copies of each face that are cropped, rotated upright,
// and scaled to a standard size as shown here:
dlib::array<array2d<rgb_pixel> > face_chips;
extract_image_chips(img, get_face_chip_details(shapes), face_chips);
win_faces.set_image(tile_images(face_chips));
cout << "Hit enter to process the next image..." << endl;
cin.get();
}
}
catch (exception& e)
{
cout << "\nexception thrown!" << endl;
cout << e.what() << endl;
}
}
// ----------------------------------------------------------------------------------------
I can choose other alternatives but I spend too much time to reach here , I want to know How I can solve this problem and load jpeg file when using DLIB
I also read these links:
Compiling libjpeg
http://www.dahlsys.com/misc/compiling_ijg_libjpeg/index.html
dlib load jpeg files
http://sourceforge.net/p/dclib/discussion/442518/thread/8a0d42dc/
I solved my problem by below instruction, please follow it.
- Add include directory in VC++
- Include source.cpp
- Add add files in dlib/external/libjpeg to project
- Define in Preprocessor
-- You don't need to use any additional library.

lodepng, stb_image. Nothing works in my system for image loading in C++

I'm trying to load pngs or bmps into my programs. But none of the libraries I found around the web works. I have no idea why but I always get "incorrect PNG signature, it's no PNG or corrupted" for EVERY png when using lodepng. "unknown pixel format" for EVERY bmp when using SDL_loadBMP. "unknown image type" for every png when using stb_image.
I can't load anything. Maybe there is something wrong with my system ? I'm using OSX Yosemite. Here is the code.
#include <iostream>
#include <string>
#define STB_IMAGE_IMPLEMENTATION
#include <lodepng.h>
#include <stb_image.h>
using namespace std;
int main (){
string name = "res/img_test.png";
const char * cstr = name.c_str();
//lodepng
unsigned char *buffer;
unsigned int w,h;
int result = lodepng_decode32_file(&buffer, &w, &h, cstr);
cout << lodepng_error_text(result) << endl;
//stb_image
int x, y, comp;
FILE *f = fopen(cstr, "rb");
unsigned char *res;
res = stbi_load_from_file(f,&x,&y,&comp,0);
fclose(f);
cout << stbi_failure_reason() << endl;
return 0;
}
I'm using latest cmake to build this with gcc. Any recommendatation is appreciated but consider this. I've tried many files (generated by me or grabbed from internet). Tested same files with other users of the these libraries. Their code worked and mine didn't.
Edit:
Here's the source with complete cmake project >> github.com/onatbas/png_load_test.git
I solved it! Thank you everyone for trying to help.
It wasn't a code issue, afterall. It is a configuration issue. My cmake script damages the pngs and bmps when trying to copy them into destination folder. The code is fine.

DescrpitorExtractor::create("SIFT") returns 0?

The following piece of code outputs 0.
Ptr<DescriptorExtractor> descriptor = DescriptorExtractor::create("SIFT");
cout << descriptor << endl;
whilethis piece of code outputs a non-zero pointer.
Ptr<DescriptorExtractor> descriptor = DescriptorExtractor::create("ORB");
cout << descriptor << endl;
What should I do to fix the create sift function? I have tested it with opencv 2.4.7 and 2.4.6.1.
SIFT and SURF are patented, nonfree.
so, to use those, you have to
include the "opencv2/nonfree/nonfree.hpp" header,
link to the opencv_nonfree.lib and
call cv::initModule_nonfree();
in main() before doing anything else.