-3

My code is working just fine in debug mode and here is the Output. Once I tried it in release mode I got this error :

Unhandled exception at 0x5E3ADF2C (msvcp120d.dll) in Project4.exe: 0xC0000005: Access violation reading location 0x00000000.

From what I read on the internet, I think it is something that has to do with uninitialized Pointer or some other variable. my bet is on : vector< vector< Point > > contours;in the findSquares function. I tried to intitialize it with everything I could think of but no luck so far.

I am using Visual Studio 2013 with OpenCV.3.0.0 the X86 version.Here is the complet code :

 #include <stdio.h>
 #include <iostream>
 #include "opencv2/core/core.hpp"
 #include "opencv2/features2d/features2d.hpp"
 #include "opencv2/highgui/highgui.hpp"
 #include "opencv2/calib3d/calib3d.hpp"
 #include <sstream>
 #include "opencv2/imgproc/imgproc.hpp"
 #include <math.h>
 #include <string.h>
 #ifndef NOMINMAX
 #define NOMINMAX
 #endif
 #include <windows.h>
 #include <algorithm>

 using namespace cv;
 using namespace std;


// helper function:
// finds a cosine of angle between vectors
// from pt0->pt1 and from pt0->pt2
static double angle(Point pt1, Point pt2, Point pt0)
{
 double dx1 = pt1.x - pt0.x;
 double dy1 = pt1.y - pt0.y;
 double dx2 = pt2.x - pt0.x;
 double dy2 = pt2.y - pt0.y;
 return (dx1*dx2 + dy1*dy2) / sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2) + 
 1e-10);
 }

 // returns sequence of squares detected on the image.
 // the sequence is stored in the specified memory storage
 static void findSquares(const Mat& image, vector<vector<Point> >& squares)
 {
    squares.clear();

    vector<vector<Point>> contours;

    // find white and yellow patch

    Mat grayscal, grayscal1;
    cvtColor(image, grayscal, CV_BGR2GRAY);
    // try several threshold levels
    for (int l = 0; l < 1; l++)
   {

       Mat imgThresholded, imgThresholded1, imgThresholded2;
      cv::adaptiveThreshold(grayscal, grayscal1, 255, 
 cv::ADAPTIVE_THRESH_MEAN_C, cv::THRESH_BINARY, 11, 0);
    inRange(grayscal, Scalar(100, 100, 100), Scalar(255, 255, 255), 
 imgThresholded1);

    //morphological closing (fill small holes in the foreground)
    //dilate(imgThresholded1, imgThresholded1, 
    getStructuringElement(MORPH_RECT, Size(7, 7)));
    erode(imgThresholded1, imgThresholded1, 
    getStructuringElement(MORPH_RECT, Size(7, 7)));

    // find contours and store them all as a list
    findContours(imgThresholded1, contours, RETR_LIST, CHAIN_APPROX_SIMPLE);
    vector<Point> approx;

    // test each contour
    for (size_t i = 0; i < contours.size(); i++)
    {
        // approximate contour with accuracy proportional
        // to the contour perimeter
        approxPolyDP(Mat(contours[i]), approx, arcLength(Mat(contours[i]), 
       true)*0.02, true);

        // square contours should have 4 vertices after approximation
        // relatively large area (to filter out noisy contours)
        // and be convex.
        // Note: absolute value of an area is used because
        // area may be positive or negative - in accordance with the
        // contour orientation
        if (approx.size() == 4 &&
            fabs(contourArea(Mat(approx))) > 4000 && 
     fabs(contourArea(Mat(approx))) < 400000 &&
            isContourConvex(Mat(approx)))
        {
            double maxCosine = 0;

            for (int j = 2; j < 5; j++)
            {
                // find the maximum cosine of the angle between joint edges
                double cosine = fabs(angle(approx[j % 4], approx[j - 2], 
     approx[j - 1]));
                maxCosine = MAX(maxCosine, cosine);
            }

            // if cosines of all angles are small
            // (all angles are ~90 degree) then write quandrange
            // vertices to resultant sequence
            if (maxCosine < 0.07)
                squares.push_back(approx);
          }
       }
     cout << "size of squares:" << squares.size() << endl;
  }
 } 
// the function draws all the squares in the image
 cv::Mat drawSquares(Mat& image, const vector<vector<Point> >& squares)
   {
  std::vector<cv::Mat> listOfMatrices, listOfMatrices2;
  vector<Point> centers;

  int m = listOfMatrices.size();
  int n = listOfMatrices2.size();
  int q = centers.size();


  for (size_t i = 0; i < squares.size(); i++)
  {

    const Point* p = &squares[i][0];

    int n = (int)squares[i].size();
    Rect r = boundingRect(Mat(squares[i]));
    cv::Size inflationSize(2, 2);
    r -= inflationSize;
    r.x = r.x + r.width / 4;
    r.y = r.y + r.height / 4;
    r.width = r.width / 2;
    r.height = r.height / 2;

    //dont detect the border

    //Mat roi = image(r);
    cv::Mat Image(image);
    cv::Mat croppedImage = Image(Rect(r.x, r.y, r.width - 4, r.height - 4));

    Point center(r.x + r.width / 2, r.y + r.height / 2);
    centers.push_back(center);
    q++;
    listOfMatrices.push_back(croppedImage);
    m++;

  }

int maxbleu = 0;
Scalar tempVal0 = mean(listOfMatrices[0]);
double myMAtMeanB0 = tempVal0.val[0];
for (int j = 1; j < q; j++)
{
    Scalar tempVal = mean(listOfMatrices[j]);
    double myMAtMeanB = tempVal.val[0];
    if (myMAtMeanB > myMAtMeanB0)
    {
        myMAtMeanB0 = myMAtMeanB;
        maxbleu = j;
    }
}

int maxdistance = 0, indicemax = 0, resmax = 0;
for (int i = 0; i < q; i++)
{
    //listOfMatrices[i].release();
    double xDiff = abs(centers[maxbleu].x - centers[i].x);
    double yDiff = abs(centers[maxbleu].y - centers[i].y);
    resmax = sqrt((xDiff * xDiff) + (yDiff * yDiff));
    if (i == maxbleu)
    {
        continue;
    }
    else if (resmax>maxdistance)
    {
        maxdistance = resmax;
        indicemax = i;
    }
}

int mindistance = 1000, indicemin = 0, resmin = 0;
for (int i = 0; i < q; i++)
{
    //listOfMatrices[i].release();
    double xDiff = abs(centers[maxbleu].x - centers[i].x);
    double yDiff = abs(centers[maxbleu].y - centers[i].y);
    resmin = sqrt((xDiff * xDiff) + (yDiff * yDiff));
    if (i == maxbleu)
    {
        continue;
    }
    else if (resmin<mindistance)
    {
        mindistance = resmin;
        indicemin = i;
    }
}
cout << "cyan" << centers[indicemax] << endl;
cout << "white" << centers[maxbleu] << endl;
cout << "gray" << centers[indicemin] << endl;

vector<Point> centersV2;
for (int j = 0; j < 4; j++)
{
    for (int i = 0; i < 6; i++)
    {
        if (abs(centers[maxbleu].x - centers[indicemax].x) < 
abs(centers[maxbleu].y - centers[indicemax].y))
        {
            if (centers[maxbleu].y - centers[indicemax].y > 0)
            {
                if (5 * abs(centers[maxbleu].x - centers[indicemin].x) > 30)
                {
                    Point tmpV2(centers[maxbleu].x - i*(centers[maxbleu].x - 
centers[indicemin].x) - j*(centers[maxbleu].x - centers[indicemax].x) / 3.3, 
centers[maxbleu].y - i*(abs(centers[maxbleu].y - centers[indicemax].y)) / 
5);
                    centersV2.push_back(tmpV2);
                }
                else {
                    Point tmpV2(centers[maxbleu].x - i*(centers[maxbleu].x - 
 centers[indicemin].x) - j*(centers[maxbleu].x - centers[indicemax].x) / 3, 
 centers[maxbleu].y - i*(abs(centers[maxbleu].y - centers[indicemax].y)) / 
 5);
                    centersV2.push_back(tmpV2);
                }
            }
            else {
                if (5 * abs(centers[maxbleu].x - centers[indicemin].x) > 30)
                {
                    Point tmpV2(centers[maxbleu].x - i*
(abs(centers[maxbleu].x - centers[indicemin].x)) - j*(abs(centers[maxbleu].x 
- centers[indicemax].x)) / 3.3, centers[maxbleu].y + i*
 (abs(centers[maxbleu].y - centers[indicemax].y) / 5));
                    centersV2.push_back(tmpV2);
                }
                else {
                    Point tmpV2(centers[maxbleu].x - i*
   (abs(centers[maxbleu].x - centers[indicemin].x)) - j*
   (abs(centers[maxbleu].x - centers[indicemax].x)) / 3, centers[maxbleu].y 
   + i*(abs(centers[maxbleu].y - centers[indicemax].y) / 5));
                    centersV2.push_back(tmpV2);
                }
            }

        }
        else {
            if (centers[maxbleu].x - centers[indicemin].x > 0)
            {
                if (5 * abs(centers[maxbleu].y - centers[indicemin].y) > 30)
                {
                    Point tmpV2(centers[maxbleu].x - i*
 (abs(centers[maxbleu].x - centers[indicemax].x) / 5) + i, 
  centers[indicemin].y - i*(centers[maxbleu].y - centers[indicemin].y) - j*
 (centers[maxbleu].y - centers[indicemax].y) / 3.3);
                    centersV2.push_back(tmpV2);
                }
                else {
                    Point tmpV2(centers[maxbleu].x - i*
(abs(centers[maxbleu].x - centers[indicemax].x) / 5) + i, 
centers[indicemin].y - i*(centers[maxbleu].y - centers[indicemin].y) - j*
(centers[maxbleu].y - centers[indicemax].y) / 3);
                    centersV2.push_back(tmpV2);
                }
            }
            else {
                if (5 * abs(centers[maxbleu].y - centers[indicemin].y) > 30)
                {
                    Point tmpV2(centers[maxbleu].x + i*
 (abs(centers[maxbleu].x - centers[indicemax].x) / 5) + i, 
 centers[maxbleu].y - i*((centers[maxbleu].y - centers[indicemin].y)) - j*
 (centers[maxbleu].y - centers[indicemax].y) / 3.3);
                    centersV2.push_back(tmpV2);
                }
                else
                {
                    Point tmpV2(centers[maxbleu].x + i*
   (abs(centers[maxbleu].x - centers[indicemax].x) / 5) + i, 
   centers[maxbleu].y - i*((centers[maxbleu].y - centers[indicemin].y)) - j*
   (centers[maxbleu].y - centers[indicemax].y) / 3);
                    centersV2.push_back(tmpV2);
                }
            }

        }

    }
  }
  for (int i = 0; i < centersV2.size(); i++)
  {
    cv::Mat IImage;
    image.copyTo(IImage);
    cv::Mat roi = IImage(Rect(centersV2[i].x - 
  0.66*listOfMatrices[maxbleu].size().width / 2, centersV2[i].y - 
  0.66*listOfMatrices[maxbleu].size().height / 2, 
  0.66*listOfMatrices[maxbleu].size().width, 
  0.66*listOfMatrices[maxbleu].size().height));
    listOfMatrices2.push_back(roi);
    n++;
    cout << "centre de patchs :" << i + 1 << " :est:" << centersV2[i] << "   
    colour :" << mean(listOfMatrices2[i]) << endl;
    rectangle(image, Point(centersV2[i].x - 
    0.66*listOfMatrices[maxbleu].size().width, centersV2[i].y - 
    0.66*listOfMatrices[maxbleu].size().height), Point(centersV2[i].x + 
    0.66*listOfMatrices[maxbleu].size().width, centersV2[i].y + 
    0.66*listOfMatrices[maxbleu].size().height), Scalar(0, 255, 0), 4, 8, 
    0);
    //ellipse(image, centersV2[i], 
   Size(0.66*listOfMatrices[maxbleu].size().width, 
   0.66*listOfMatrices[maxbleu].size().height), 0, 0, 360, Scalar(0, 255, 
   0), 2, LINE_AA);

    stringstream numero;
    numero << i + 1;
    putText(image, numero.str(), Point(centersV2[i].x - 15, centersV2[i].y + 
  5), 5, 2, Scalar(0, 0, 255), 4, 8, false);
 }

}

 int main(int /*argc*/, char** /*argv*/)
{

static const char* filename[] = { "E:/Zouhair Jimmouh-Colorimetrie/Example 
 Etudes/Exemple2/AS1606001A-008-R045-HP-01.jpg", 0};

  vector<vector<Point> > Squares;

  for (int i = 0; filename[i] != 0; i++)
  {
    Mat Image = imread(filename[i], 1);
    if (Image.empty())
    {
        cout << "Couldn't load " << endl;
        //continue;
    }

    Mat blackTOwhite;
    findSquares(Image, Squares);
    (drawSquares(Image, Squares)).copyTo(blackTOwhite);
    //show image with detected patches
    namedWindow("RECT", CV_WINDOW_NORMAL);
    imshow("RECT", Image);

    int c = waitKey();
    if ((char)c == 27)
        break;
  }

  return 0;
 }

Any help guys is appreciated ! i've been struggling with this for days now.

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
  • 3
    Please try to create a [**Minimal**, Complete, and Verifiable Example](http://stackoverflow.com/help/mcve) to show us. Also please [read about how to ask good questions](http://stackoverflow.com/help/how-to-ask). – Some programmer dude Jun 27 '17 at 09:03
  • 1
    You're linking to debug libraries in release. – Miki Jun 27 '17 at 09:04
  • 1
    The right tool to solve such problems is your debugger. You should step through your code line-by-line *before* asking on Stack Overflow. For more help, please read [How to debug small programs (by Eric Lippert)](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/). At a minimum, you should [edit] your question to include a [Minimal, Complete, and Verifiable](http://stackoverflow.com/help/mcve) example that reproduces your problem, along with the observations you made in the debugger. – πάντα ῥεῖ Jun 27 '17 at 09:04
  • What did your debugger tell you? – Jabberwocky Jun 27 '17 at 09:06
  • @Miki I am sure it is not the libraries , that's the first thing i verified! – zouhair jim Jun 27 '17 at 09:18
  • You verified it wrong. Why are you trying to load the debug runtime `msvcp120d.dll` then? – Miki Jun 27 '17 at 09:21
  • @MichaelWalz Thanks for the edit, i tried to debug line by line and when i got to the part where i need to use "vector< vector< Point > > contours" , i got that error message! – zouhair jim Jun 27 '17 at 09:21
  • @Miki i am using x86 version of OpenCV , Visual studio also is x86 and my windows 10 is x64. i linked both opencv_world300d.lib and opencv_world300.lib in Additional Dependencies. i dont know what is this msvcp120d.dll does ! i am not very advanced c++ user – zouhair jim Jun 27 '17 at 09:29
  • Yeah.... don't link to both of them. Just opencv_world300d.lib in debug, and opencv_world300.lib in release – Miki Jun 27 '17 at 09:30

1 Answers1

2

You're mixing debug and release libraries in your linking settings.

From the comments to the question:

I linked both opencv_world300d.lib and opencv_world300.lib in Additional Dependencies.

You shouldn't link to both of them. Link to:

  • opencv_world300d.lib in Debug
  • opencv_world300.lib in Release
Miki
  • 40,887
  • 13
  • 123
  • 202