OpenCV HOGDescriptor Errors - c++

I am running OpenCV 2.4.3 on Mac OS X 10.8.
I am trying to use the cv::HOGDescriptor to get pedestrians in a video sequence.
This is the code I am using to do the detection and paint a bounding box.
cv::VideoCapture input("file.avi");
assert(input.isOpened());
cv::HOGDescriptor body;
assert(body.load("hogcascade_pedestrians.xml"));
cv::Mat frame, gray;
cv::namedWindow("video");
while (input.read(frame)) {
vector<cv::Rect> rects;
cv::cvtColor(frame, gray, cv::COLOR_RGB2GRAY);
cv::equalizeHist(gray, gray);
body.detectMultiScale(gray, rects);
for (unsigned int i=0;i<rects.size();i++) {
cv::rectangle(frame, cv::Point(rects[i].x, rects[i].y),
cv::Point(rects[i].x+rects[i].width, rects[i].y+rects[i].height),
cv::Scalar(255, 0, 255));
}
cv::imshow("video", frame);
}
However, when the execution reaches the line body.detectMultiScale(gray, rects);, I get the an error and the whole application crashes
libc++abi.dylib: terminate called throwing an exception
[1] 92156 abort ../bin/DetectPedestrians
What is going wrong? I cannot seem to get any new information from the gdb or lldb outputs. I am compiling with the code with a CMake build, so I guess this isn't a problem with the linking.
Here is a stack trace from the thread that crashed -
Thread 0 Crashed:: Dispatch queue: com.apple.root.default-priority
0 libsystem_kernel.dylib 0x00007fff8c001212 __pthread_kill + 10
1 libsystem_c.dylib 0x00007fff8e7afaf4 pthread_kill + 90
2 libsystem_c.dylib 0x00007fff8e7f3dce abort + 143
3 libc++abi.dylib 0x00007fff94096a17 abort_message + 257
4 libc++abi.dylib 0x00007fff940943c6 default_terminate() + 28
5 libobjc.A.dylib 0x00007fff8e11f887 _objc_terminate() + 111
6 libc++.1.dylib 0x00007fff96b0b8fe std::terminate() + 20
7 libobjc.A.dylib 0x00007fff8e11f5de objc_terminate + 9
8 libdispatch.dylib 0x00007fff8c4ecfa0 _dispatch_client_callout2 + 28
9 libdispatch.dylib 0x00007fff8c4ed686 _dispatch_apply_serial + 28
10 libdispatch.dylib 0x00007fff8c4e80b6 _dispatch_client_callout + 8
11 libdispatch.dylib 0x00007fff8c4ebae8 _dispatch_sync_f_invoke + 39
12 libopencv_core.2.4.3.dylib 0x0000000101d5d900 cv::parallel_for_(cv::Range const&, cv::ParallelLoopBody const&, double) + 116
13 libopencv_objdetect.2.4.3.dylib 0x000000010257fa21 cv::HOGDescriptor::detectMultiScale(cv::Mat const&, std::vector<cv::Rect_<int>, std::allocator<cv::Rect_<int> > >&, std::vector<double, std::allocator<double> >&, double, cv::Size_<int>, cv::Size_<int>, double, double, bool) const + 559
14 libopencv_objdetect.2.4.3.dylib 0x000000010257fdc2 cv::HOGDescriptor::detectMultiScale(cv::Mat const&, std::vector<cv::Rect_<int>, std::allocator<cv::Rect_<int> > >&, double, cv::Size_<int>, cv::Size_<int>, double, double, bool) const + 80
15 DetectPedestrians 0x0000000101a7886c main + 2572 (detect.cpp:41)
16 libdyld.dylib 0x00007fff8d89f7e1 start + 1
On a Linux system, the same code gives me an error saying -
OpenCV Error: Assertion failed (dsize.area() || (inv_scale_x > 0 && inv_scale_y > 0)) in resize, file /home/subho/OpenCV/OpenCV-2.4.3/modules/imgproc/src/imgwarp.cpp, line 1726
terminate called after throwing an instance of 'tbb::captured_exception'
what(): /home/subho/OpenCV/OpenCV-2.4.3/modules/imgproc/src/imgwarp.cpp:1726: error: (-215) dsize.area() || (inv_scale_x > 0 && inv_scale_y > 0) in function resize

I havent been able to track down why exactly this error occurs. However it has something to do with how the XML HOG cascade file is loaded into memory.
I have reported this as an bug in the OpenCV issue tracker and am waiting to hear back from the developers.
Temporarily, my workaround for this problem is to directly set the SVM parameters in the cv::HOGDescriptor class like so
cv::HOGDescriptor human;
human.setSVMDetector(cv::HOGDescriptor::getDefaultPeopleDetector());
This seems to be working on both the Mac OSX and the linux versions of OpenCV 2.4.3

i am not an expert on this area, but i think you get the assertion failed error cause of size missmatch problems. i would suggest initilizing rects with some predifined size and see if you get the same error.
hope this helps

I've the same problem like yours here: HOGDescriptor Error and Assertion Failed
but try this out!
change your...
cv::HOGDescriptor body;
to...
cv::CascadeClassifier body;
it works like a charm! it can detect the pedestrian! :)
but there's another problem, this program run slowly! SO LAGGY! :))

Related

How to use shift and offset attributes in function fillPoly

I'm looking for easiest way to apply an offset to minimize mask on the image. I tried to use function fillPoly. The names of attributes 'shift' and 'offset', especially the latter one sounded good. Unfortunately I got error: -215 Assertion failed, when I tried to use it.
I cannot find any examples with usage of these attributes. Can any body point me ?
It's not the whole code but help understand my issue.
std::vector<std::vector<cv::Point> > fillContAll;
fillContAll.push_back(fillContSingle);
cv::Mat maska;
srcImage.copyTo(maska);
maska.setTo(0);
cv::fillPoly(maska, fillContAll, cv::Scalar(255, 255, 255),8,50);
// I tried also cv::fillPoly(maska, fillContAll, cv::Scalar(255, 255, 255),8,(5,5));
The whole error message is:
exception thrown!
OpenCV(4.2.0) C:\build\master_winpack-build-win64-vc15\opencv\modules\imgproc\src\drawing.cpp:2005: error: (-215:Assertion failed) pts && npts && ncontours >= 0 && 0 <= shift && shift <= XY_SHIFT in function 'cv::fillPoly'

Specifying shapehandle's shape when creating new op in tensorflow (rank problem of the output tensor)

I have successfully compiled the op registration file and tested when only using this file. But during training process, I tried to call the function defined in the op, these errors were encountered, which vary every time:
Segmentation fault (core dumped)
or
double free or corruption (!prev)
Aborted (core dumped)
or
ValueError: Shape must be rank 1 but is rank 99648624 for 'x' (op: 'x') with input shapes: [50, 1000, 3].
And please note the number99648624 above is uncertain, sometimes it could be 0 or any weird number.
Below is the code for registering the op in tensorflow, where I specify the output's dimension as (b,200,200,1):
.SetShapeFn([](::tensorflow::shape_inference::InferenceContext* c) {
::tensorflow::shape_inference::ShapeHandle input
TF_RETURN_IF_ERROR(c->WithRank(c->input(0), 3, &input));
::tensorflow::shape_inference::ShapeHandle dim2;
TF_RETURN_IF_ERROR(c->MakeShapeFromShapeTensor(200, &dim2));
::tensorflow::shape_inference::ShapeHandle dim3;
TF_RETURN_IF_ERROR(c->MakeShapeFromShapeTensor(200, &dim3));
::tensorflow::shape_inference::ShapeHandle dim4;
TF_RETURN_IF_ERROR(c->MakeShapeFromShapeTensor(1, &dim4));
::tensorflow::shape_inference::ShapeHandle output = c->MakeShape({c->Dim(input, 0), c->Dim(dim2, 0), c->Dim(dim3, 0), c->Dim(dim4, 0)});
c->set_output(0, output);
return Status::OK();
});
Thank you in advance! Any suggestion is welcome!
According to the comments in tensorflows source code, MakeShapeFromShapeTensor takes an ID as the input:
Returns in out a new shape whose dimension sizes come from input tensor
input_idx. The tensor must be a 1-dimensional int32 or int64 tensor. If
the input tensor is NULL, then an unknown shape is returned.
So it takes the tensor you declared as an input with index input_idx and tries to use it as the shape (instead of using the shape ot the tensor like with c->input(0) does). So if you declared your inputs like this:
REGISTER_OP("SomeOp")
.Input("some_input: float")
.Input("some_vector: int64")
and some_vector is for example (2,2,1) then c->MakeShapeFromShapeTensor(1, &dims) will output into dims a ShapeHandle with dimensions (2,2,1).
So what you actually want is to set the dimensions directly when calling MakeShape like this:
c->MakeShape({c->Dim(input, 0), 200, 200, 1});
Your errors come from the fact that in c++ there are not many checks performed when accessing invalid indices, so it tries to load whatever value is in the ram where index 200 would be and convert it into an integer vector. Accessing this memory adress is either not allowed (Segmentation Fault) or it contains invalid values (corruption) or garbage (random high rank).

QWidget::paintEngine being called from QCoreApplication::processEvents

I'm converting an OSX application from Qt 4/Carbon to Qt5.11 with the QOpenGLWidget.
I've moved the drawing "calls" to my overridden QOpenGlWidget::paintGL().
The problem is I'm still getting these messages on the console:
QWidget::paintEngine: Should no longer be called
Getting a stack trace, I've discovered that this is being called eventually from QCoreApplication::processEvents, which I'm calling from my own internal event loop.
Here's a stack trace (edited for readability)
thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: libQt5Widgets_debug.5.dylibQWidget::paintEngine()
frame #1: libQt5Widgets_debug.5.dylibQOpenGLWidget::paintEngine(0)
frame #2: libQt5Gui_debug.5.dylibQPainter::begin()
frame #3: libQt5Gui_debug.5.dylibQPainter::QPainter()
frame #4: libQt5Gui_debug.5.dylibQPainter::QPainter()
frame #5: libQt5Widgets_debug.5.dylibQWidgetPrivate::drawWidget()
frame #6: libQt5Widgets_debug.5.dylibQWidgetPrivate::repaint_sys()
frame #7: libQt5Widgets_debug.5.dylibQWidgetPrivate::syncBackingStore()
frame #8: libQt5Widgets_debug.5.dylibQWidgetWindow::handleExposeEvent()
frame #9: libQt5Widgets_debug.5.dylibQWidgetWindow::event()
frame #10: libQt5Widgets_debug.5.dylibQApplicationPrivate::notify_helper()
frame #11: libQt5Widgets_debug.5.dylibQApplication::notify()
frame #12: libQt5Core_debug.5.dylibQCoreApplication::notifyInternal2()
frame #13: libQt5Gui_debug.5.dylibQCoreApplication::sendSpontaneousEvent()
frame #14: libQt5Gui_debug.5.dylibQGuiApplicationPrivate::processExposeEvent()
frame #15: libQt5Gui_debug.5.dylibQGuiApplicationPrivate::processWindowSystemEvent()
frame #16: libQt5Gui_debug.5.dylibbool QWindowSystemInterfacePrivate::handleWindowSystemEvent<QWindowSystemInterface::SynchronousDelivery>()
frame #17: libQt5Gui_debug.5.dylibvoid QWindowSystemInterface::handleExposeEvent()
frame #18: libqcocoa_debug.dylibQCocoaWindow::handleExposeEvent()
frame #19: libqcocoa_debug.dylib::-[QNSView updateRegion:](self=0x000061200039fc40, _cmd="updateRegion:", dirtyRegion=QRegion # 0x00007ffeefbf9b18)
frame #20: libqcocoa_debug.dylib::-[QNSView updateLayer](self=0x000061200039fc40, _cmd="updateLayer")
frame #21: AppKit_NSViewUpdateLayer + 45
frame #22: AppKit-[_NSViewBackingLayer display] + 495
frame #23: QuartzCoreCA::Layer::display_if_needed(CA::Transaction*) + 634
frame #24: QuartzCoreCA::Context::commit_transaction(CA::Transaction*) + 319
frame #25: QuartzCoreCA::Transaction::commit() + 576
frame #26: QuartzCoreCA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) + 66
frame #27: CoreFoundationCFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION + 23
frame #28: CoreFoundation__CFRunLoopDoObservers + 452
frame #29: CoreFoundationCFRunLoopRunSpecific + 523
frame #30: HIToolboxRunCurrentEventLoopInMode + 293
frame #31: HIToolboxReceiveNextEventCommon + 618
frame #32: HIToolbox_BlockUntilNextEventMatchingListInModeWithFilter + 64
frame #33: AppKit_DPSNextEvent + 997
frame #34: AppKit-[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 1362
frame #35: libqcocoa_debug.dylibQCocoaEventDispatcher::processEvents(this=0x00006040000dbdf0, flags=(i = 0)) at qcocoaeventdispatcher.mm:482
frame #36: libQt5Core_debug.5.dylib`QCoreApplication::processEvents(flags=(i = 0)) at qcoreapplication.cpp:1252
The problem is that ::processEvents is eventually calling ::paintEngine for the QOpenGLWidget, OUTSIDE of ::paintGL, but it's totally out of my control.
FWIW, the Event driving this is a QEvent::UpdateRequest.
I tried overriding ::event in my QOpenGLWidget-inheriting class to call QOpenGlWidget::update when it receives a QEvent::UpdateRequest, but that just ended up making the app non-responsive.
How should I handle ::processEvents attempting to draw QOpenGlWidgets?
Thanks!
I fixed this by removing this statement from our QOpenGlWidget subclass:
setAttribute( Qt::WA_PaintOnScreen, true );
Removing this got ride of the paintEngine calls (and solved all kinds of other problems).

Loading large JPG images in qt fails [duplicate]

Are there any known size/space limitation of QPixmap and/or QImage objects documented? I did not find any useful information regarding this. I'm currently using Qt 4.7.3 on OSX and Windows. Particulary I'm interested in:
Width/Height limits?
Limits depending on color format?
Difference between 32/64 bit machines?
Difference regarding OS?
I would naively suspect that memory is the only limitation, so one could calculate max size by
width x height x byte_per_pixel
I assume that there is a more elaborate rule of thumb; also 32 bit machines may have addressing problems when you run into GB dimensions.
In the end I want to store multiple RGBA images of about 16000x16000 pixel in size and render them using transparency onto each other within a QGraphicsScene. The workstation available can have a lot of RAM, let's say 16GB.
tl;dr: What size limits of QImage/QPixmap are you aware of, or where can I find such information?
Edit: I'm aware of the tiling approach and I'm fine with that. Still it would be great to know the things described above.
Thanks!
Both are limited to 32767x32767 pixels. That is, you can think of them as using a signed 16-bit value for both the X and Y resolution.
No axis can ever exceed 32767 pixels, even if the other axis is only 1 pixel. Operating system "bitness" does not affect the limitation.
The underlying system may run into other limits, such as memory as you mentioned, before such a huge image can be created.
You can see an example of this limitation in the following source code:
http://git.zx2c4.com/qt/plain/src/gui/image/qpixmap_x11.cpp
if (uint(w) >= 32768 || uint(h) >= 32768) {
w = h = 0;
is_null = true;
return;
}
Building on the answer by #charles-burns, here is relevant source code for QImage:
QImageData *d = 0;
if (format == QImage::Format_Invalid)
return d;
const int depth = qt_depthForFormat(format);
const int calc_bytes_per_line = ((width * depth + 31)/32) * 4;
const int min_bytes_per_line = (width * depth + 7)/8;
if (bpl <= 0)
bpl = calc_bytes_per_line;
if (width <= 0 || height <= 0 || !data
|| INT_MAX/sizeof(uchar *) < uint(height)
|| INT_MAX/uint(depth) < uint(width)
|| bpl <= 0
|| height <= 0
|| bpl < min_bytes_per_line
|| INT_MAX/uint(bpl) < uint(height))
return d; // invalid parameter(s)
So here, bpl is the number of bytes per line, which is effectively width * depth_in_bytes. Using algebra on that final invalid test:
INT_MAX/uint(bpl) < uint(height)
INT_MAX < uint(height) * uint(bpl)
INT_MAX < height * width * depth_in_bytes
So, your image size in total must be less than 2147483647 (for 32-bit ints).
I actually had occasion to look into this at one time. Do a search in the source code of qimage.cpp for "sanity check for potential overflows" and you can see the checks that Qt is doing. Basically,
The number of bytes required (width * height * depth_for_format) must be less than INT_MAX.
It must be able to malloc those bytes at the point you are creating the QImage instance.
Are you building a 64 bit app? If not, you are going to run into memory issues very quickly. On Windows, even if the machine has 16GB ram, a 32 bit process will be limited to 2GB (Unless it is LARGEADDRESSAWARE then 3GB). A 16000x16000 image will be just under 1 GB, so you'll only be able to allocate enough memory for 1, maybe 2 if you are very lucky.
With a 64 bit app you should be able to allocate enough memory for several images.
When I try to load JPEG with size 6160x4120 to QPixmap I get this warning: "qt.gui.imageio: QImageIOHandler: Rejecting image as it exceeds the current allocation limit of 128 megabytes" and returns empty QPixmap.
This seems to be the most strict constraint I have found so far.
There is however an option to increase this limit with void QImageReader::setAllocationLimit(int mbLimit).

Weird crash when I try to attribute a variable in OpenCV IOS

There is something I'm not able to understand. I'm using OpenCV IOS for my IOS Device.
I have a C++ class with a private variable cv::Rect . This variable is located to my .h file.
In my .cpp file, I have a method which creates a cv::Rect. Then, I would like to attribute this new created cv::Rect to my class variable but It crashs and I do not understand why.
.h file
class detection {
public:
detection();
cv::Mat processImage(cv::Mat frame);
cv::Mat detectFace(cv::Mat frame);
public:
cv::Rect getRectangleDetection();
void setRectangleDetection(cv::Rect& rect);
private:
cv::Rect _rectangeDetect;
};
.cpp file
cv::Mat detection::processImage(cv::Mat frame){
Mat originalColorImage;
frame.copyTo(originalColorImage);
int cx = frame.cols/2;
int cy = frame.rows/2;
int width = 1000;
int height = 1000;
NSLog(#"[INFO] Rectangle creation");
cv::Rect rect1(cx-width/2, cy-height/2, width,height);
cv::Rect test2;
//test2 = rect1;//It works !
setRectangleDetection(rect1); // or _rectangeDetect = rect1 --> both don't work
cv::rectangle( originalColorImage,rect1,
cv::Scalar(255, 0, 0),4);
return originalColorImage;
}
I took a look at the crash report and I saw that :
exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000000000000
Triggered by Thread: 0
Filtered syslog:
None found
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 detect 0x000000010007f580 cv::Rect_<int>::operator=(cv::Rect_<int> const&) (types.hpp:1689)
1 detect 0x000000010007f504 OpenCV::setRectangleDetection(cv::Rect_<int>) (OpenCV.mm:172) //This is the setter but If I'm not using the setter the error will come from _rectangleDetect = rect1.
I tried also to initialize the variable cv::Rect but same behavior.
Do you have any idea what's happen ? Really, I tried to figure out why but without success.
I used a lot OpenCv before and It's the first time something like that happens.
Thank !
Okey I found the problem. It was a silly one.
Actually, on my other class when I was using the detection class, I forgot to initialize the object.
Detection _detect = new Detection()
As I did not get any error from the following line and by the fact that the behavior seemed to be good (even with some debug), I did not think of that.
_detect->processImage(frame);
Thank you guys anyway.