Matthew
Matthew

Reputation: 286

Segmentation fault, can't find where I did wrong

I cannot find where I did wrong in this C++ code for my raspberry pi, it gives me a segmentation fault but after looking for 4 hours and searching here I see nothing wrong

To my knowledge segmentation faults happen when a program is trying to access memory that isn't his, but I don't see this happening anywhere.

I'm basically trying to find a certain coloured object with the raspberry pi module

#include <cv.h>
#include <highgui.h>
#include <stdio.h>
#include <unistd.h>
#include "RaspiCamCV.h"

using namespace cv;

int main(int argc, char *argv[ ]){

    RASPIVID_CONFIG * config = (RASPIVID_CONFIG*)malloc(sizeof(RASPIVID_CONFIG));

    config->width=320;
    config->height=240;
    config->bitrate=0;      // zero: leave as default
    config->framerate=0;
    config->monochrome=0;

    int opt;

    while ((opt = getopt(argc, argv, "lxm")) != -1)
    {
        switch (opt)
        {
            case 'l':                                       // large
                config->width = 640;
                config->height = 480;
                break;
            case 'x':                                       // extra large
                config->width = 960;
                config->height = 720;
                break;
            case 'm':                                       // monochrome
                config->monochrome = 1;
                break;
            default:
                fprintf(stderr, "Usage: %s [-x] [-l] [-m] \n", argv[0], opt);
                fprintf(stderr, "-l: Large mode\n");
                fprintf(stderr, "-x: Extra large mode\n");
                fprintf(stderr, "-l: Monochrome mode\n");
                exit(EXIT_FAILURE);
        }
    }

    /*
     Could also use hard coded defaults method: raspiCamCvCreateCameraCapture(0)
     */
    RaspiCamCvCapture * capture = (RaspiCamCvCapture *) raspiCamCvCreateCameraCapture2(0, config);
    free(config);

    CvFont font;
    double hScale=0.4;
    double vScale=0.4;
    int    lineWidth=1;

    cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX|CV_FONT_ITALIC, hScale, vScale, 0, lineWidth, 8);

    cvNamedWindow("RaspiCamTest", 1);
    int exit = 0;
    IplImage* x;
    IplConvKernel* erodeElement;
    IplConvKernel* dilateElement;

    printf("start");


    do {
        IplImage* image = raspiCamCvQueryFrame(capture);
        cvCvtColor(image, x, COLOR_BGR2HSV);

        cvInRangeS(&x, cvScalar(0,137,171), cvScalar(48,256,248), x);

        char text[200];
        sprintf(text, "Press ESC to exit");
        cvPutText(x, text, cvPoint(05, 80), &font, cvScalar(255, 255, 0, 0));

        printf("hi");

        erodeElement = cvCreateStructuringElementEx(3,3,-1,-1,MORPH_RECT);
        dilateElement = cvCreateStructuringElementEx(6,6,-1,-1,MORPH_RECT);

        cvErode(x,x,erodeElement);
        cvErode(x,x,erodeElement);

        cvDilate(x,x,dilateElement);
        cvDilate(x,x,dilateElement);



        cvShowImage("RaspiCamTest2", static_cast<CvArr*>(&x));
        cvShowImage("RaspiCamTest", image);

        char key = cvWaitKey(10);

        switch(key)
        {
            case 27:                // Esc to exit
                exit = 1;
                break;
            case 60:                // < (less than)
                raspiCamCvSetCaptureProperty(capture, RPI_CAP_PROP_FPS, 25);    // Currently NOOP
                break;
            case 62:                // > (greater than)
                raspiCamCvSetCaptureProperty(capture, RPI_CAP_PROP_FPS, 30);    // Currently NOOP
                break;
        }

    } while (!exit);

    cvDestroyWindow("RaspiCamTest");
    raspiCamCvReleaseCapture(&capture);
    return 0;
}

Upvotes: 0

Views: 611

Answers (2)

KalyanS
KalyanS

Reputation: 527

In addition to the points above:

why do you pass the address of 'x' and 'x' itself in the same function call.

cvInRangeS(>>&x<<, cvScalar(0,137,171), cvScalar(48,256,248), >>x<<);

One of them seems to be incorrect. By passing in &x, do you intend to allocate space and set the pointer. If so, why do you pass in 'x' separately.

Inside the body of cvInRangeS(), the second x will be pointing you to uninitialized memory, even if you fill in the pointer corresponding to the first argument.

This is because all the arguments are evaluated and passed in, including the last parameter as it exists at call-time. The first argument '&x' achieves a side-effect of updating the caller's view, but, it is not available within the body for the second parameter.

Upvotes: 1

The Dark
The Dark

Reputation: 8514

It may not be the only problem, but x is uninitialized when you pass it to cvCvtColor. The dst pointer you pass to cvCvtColor needs to point to "The destination image of the same data type as the source one." (from this page)

This meand the cvCvtColor call will write to a random location in memory, possibly causing a crash immediately or later.

Upvotes: 1

Related Questions