Search code examples
c++imagemacosopencvdecoding

OpenCV C++ imgdecode generating an exception on OSX


I have an application that takes pictures from the camera, encode them, do some stuff and then decode them. It works on Ubuntu, but on OSX imgdecode is generating the following exception:

libc++abi.dylib: terminating with uncaught exception of type cv::Exception: OpenCV(4.2.0) /tmp/opencv-20200404-3398-7w1b75/opencv-4.2.0/modules/imgcodecs/src/loadsave.cpp:732: error: (-215:Assertion failed) buf.checkVector(1, CV_8U) > 0 in function 'imdecode_'

Abort trap: 6

I tried to encode and decode the image in the same script to have a minimal verifiable example. The script is the following:

#include "opencv2/opencv.hpp"
#include<unistd.h>
using namespace std;
using namespace cv;

int main(int argc, char *argv[])
{
    Mat frame;
    VideoCapture cam(0);
    std::vector<uchar> buf_in;
    u_char *buf ;
    while(1)
    {
        cam>>frame;
        imencode(".png",frame, buf_in);
        //encode image and put data into the vector buf
        frame  = cv::imdecode(cv::Mat(3, buf_in.size(), CV_8UC3, buf_in.data()), 1);
        imshow("window", frame);
        waitKey(2);
    }
    return 0;

}

and it is still generating the exception on OSX. Why is that? Why is the exception generated? Why only on OSX?

POST SCRIPTA

If one needs to compile the code, the following Makefile can be used:

CXX = g++

CXXFLAGS = -std=c++11 -pg
INC_PATH = `pkg-config --cflags opencv4`

LIBS = `pkg-config --libs opencv4`

SOURCEDIR := ./
SOURCES := $(wildcard $(SOURCEDIR)/*.cpp)
OBJDIR=$(SOURCEDIR)/obj

OBJECTS := $(patsubst $(SOURCEDIR)/%.cpp,$(OBJDIR)/%.o, $(SOURCES))
DEPENDS := $(patsubst $(SOURCEDIR)/%.cpp,$(OBJDIR)/%.d,$(SOURCES))
WARNING := -Wall -Wextra

.PHONY: all clean

all: openCV

clean:
    $(RM) $(OBJECTS) $(DEPENDS) openCV

openCV: $(OBJECTS)
    $(CXX) $(WARNING) $(CXXFLAGS) $(INC_PATH) $^ -o $@ $(LIBS)

-include $(DEPENDS)

$(OBJDIR):
    mkdir -p $(OBJDIR)

$(OBJDIR)/%.o: $(SOURCEDIR)/%.cpp Makefile | $(OBJDIR)
    $(CXX) $(WARNING) $(CXXFLAGS) $(INC_PATH) -MMD -MP -c $< -o $@

Solution

  • I solved changing the argument of imdecode to be a vector<u_char> containing the raw data, instead of initialising a new Mat structure.

    #include "opencv2/opencv.hpp"
    #include<unistd.h>
    using namespace std;
    using namespace cv;
    
    int main(int argc, char *argv[])
    {
        Mat frame;
        VideoCapture cam(0);
        std::vector<uchar> buf_in;
        u_char *buf ;
        while(1)
        {
            cam>>frame;
            imencode(".png",frame, buf_in);
            //encode image and put data into the vector buf
            buf_out.assign(buf_in.data, buf_in.data+buf_in.size());
            frame  = cv::imdecode(buf_out, 1);
            imshow("window", frame);
            waitKey(2);
        }
        return 0;
    
    }