2

I want to create an array of matrices for segment the image.

Here is what I do for creating array, and it shows an error of "EXC_I386_GPFLT".

How can I fix it or What should I do to achieve my purpose?

#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "iostream"

using namespace cv;
using namespace std;

int main( )
{

    Mat img;
    img = imread("/Users/koike1979/Documents/0306/trucka.bmp", CV_LOAD_IMAGE_COLOR);
    namedWindow( "Original image", CV_WINDOW_AUTOSIZE );
    imshow( "Original image", img );

    Mat H[2]= {Mat(20,20,CV_8UC1),Mat(20,20,CV_8UC1)};

    for (int i=0; i<200; i++)
        for (int j=0; j<200; j++)
    {

    Vec3b intensity2 = img.at<Vec3b>(i ,j);
    int blue = intensity2.val[0];
    int green = intensity2.val[1];
    int red = intensity2.val[2];
        H[0].at<uchar>(i,j)=(blue+green+red)/3;
            }
    namedWindow( "Modify pixel", CV_WINDOW_AUTOSIZE );
    imshow( "Modify pixel", H[0] );
    waitKey(0);

    return 0;
}
Humam Helfawi
  • 19,566
  • 15
  • 85
  • 160
John Lee
  • 21
  • 3
  • Use List or ArrayList instead. – Suhyeon Lee Mar 09 '16 at 11:30
  • I'm sorry, you're using C++ then you can use vector instead – Suhyeon Lee Mar 09 '16 at 11:37
  • Are you aware that you're are using indices out of bound for your matrices? H[0] is 20x20, while you're accessing values up to 200x200. Aside from that, and the fact that you can code this in a better way, this code works for me – Miki Mar 09 '16 at 13:31

2 Answers2

1

https://stackoverflow.com/a/19652248/4518710

What's your main purpose of creating an array of matrices?
Your code seems to have some issues,

First of all, you need to access coordinate of Mat NOT by hardcoding.
Use Mat::rows and Mat::cols instead.
original:

for (int i=0; i<200; i++)
    for (int j=0; j<200; j++)
    {
    }


modified:

int rows = img.rows;
if(rows > 200)
    rows = 200;
int cols = img.cols;
if(cols > 200)
    cols = 200;

for (int i=0; i<rows; i++)
    for (int j=0; j<cols; j++)
    {
    }


Second, use vector<> feature of C++ instead of array itself.
original:

Mat H[2]= {Mat(20,20,CV_8UC1),Mat(20,20,CV_8UC1)};

modified:

std::vector<Mat> H;
H.push_back(Mat(20, 20, CV_8UC1));
H.push_back(Mat(20, 20, CV_8UC1));


Third, directly casting int to uchar can cause potential side effects.
Use static_cast instead.
original:

H[0].at<uchar>(i,j)=(blue+green+red)/3;


modified:

H[0].at<uchar>(i,j) = static_cast<uchar>((blue+green+red)/3);
Community
  • 1
  • 1
Suhyeon Lee
  • 569
  • 4
  • 18
0

You might use an std::vector

Mat img;
img = imread("./res/mydhm.png", CV_LOAD_IMAGE_COLOR);
namedWindow("Original image", CV_WINDOW_AUTOSIZE);
imshow("Original image", img);

//Mat H[2] = { Mat(img.cols, img.row, img.type), Mat(img.cols, img.row, img.type) };
std::vector<Mat> H; // use vector
H.push_back(Mat(img.cols, img.rows, img.type()));
H.push_back(Mat(img.cols, img.rows, img.type()));

for (int i = 0; i<img.cols; i++)
{
    for (int j = 0; j<img.rows; j++)
    {
        Vec3b intensity2 = img.at<Vec3b>(Point(i, j));
        int blue = intensity2.val[0];
        int green = intensity2.val[1];
        int red = intensity2.val[2];
        H[0].at<Vec3b>(Point(i, j)) = (uchar)(blue + green + red) / 3;
    }
}
namedWindow("Modify pixel", CV_WINDOW_AUTOSIZE);
imshow("Modify pixel", H[0]);
waitKey(0);

don't forget to #include<vector>

Zoltán
  • 678
  • 4
  • 15