Domanda

I am trying to rewrite the value for a pixel in a Mat-type grayscale image using Visual Studio Express 2012 for Windows Desktop. I've tried:

imgGrayComp.at<uchar>(5, 4) = 0; 

.

imgGrayComp.ptr(4)[5] = 0; 

.

imgGrayComp.at<Vec3b>(5, 4) = 0;

But it gives me this instead:

OpenCV Error: Assertion failed (dims <= 2 && data && (unsigned)i0 < (unsigned)size.p[0] && (unsigned)(i1DataType<_Tp>::channels) < (unsigned)(size.p[1]channels()) && ((((sizeof(size_t)<<28)|0x8442211) >> ((DataType<_Tp>::depth) & ((1 << 3) - 1))*4) & 15) == elemSize1()) in cv::Mat::at, file c:\opencv\build\include\opencv2\core\mat.hpp, line 537

==========================================================================================

EDIT - Here's the code:

Calling classify():

classify("./src/0.jpg", contour, hierarchy, mDatabase, '0');

In classify():

void classify(std::string imageFile, 
    vector<vector<Point> > contour,
    vector<Vec4i> hierarchy, float mDatabase [][charsToClassify],
    char whichChar)
{
    Mat image = imread(imageFile, 1);
    Mat imageGrayClassify;

    image.convertTo(imageGrayClassify, COLOR_BGR2GRAY);
    int numPoints = computeNumContourPts(imageGrayClassify); // calling compute...()
}

In compute...():

int computeNumContourPts(Mat imgGrayComp)
{

    // dilation x1 (increases workload):
    dilate(imgGrayComp, imgGrayComp, Mat(), Point(-1,-1), 2);
    // erosion x1 (decreases workload):
    erode(imgGrayComp, imgGrayComp, Mat(), Point(-1,-1), 1);

    imgGrayComp.at<uchar>(5, 4) = 0;
}
È stato utile?

Soluzione

The problem lies in the fact that:

Instead of using cv::cvtColor(image, imageGrayClassify, CV_BGR2GRAY);, you used image.convertTo() which is meant to convert the datatype of the image.

In regard to the comment of a new error to Canberk's answer, it's simple, chances are your image is null/empty.

Use

CV_Assert(!image.empty()); //use this then the cvtColor, note this is a comment!!!

cvtColor(image,imageGrayClassify, CV_BGR2GRAY);

Alternatively, you can just use imshow to see if image is displayed successfully before even using cvtColor. Cheers.

Altri suggerimenti

With the wrong call of convertTo, you are converting your image to 64F precision.

What you do here

image.convertTo(imageGrayClassify, COLOR_BGR2GRAY);

is equivalent to

image.convertTo(imageGrayClassify, CV_64F);

since convertTo expects a data type enum; not a conversion enum. Your conversion enum (COLOR_BGR2GRAY = 6) is converted to data type enum (CV_64F = 6).

I suppose you meant to use cvtColor there.

And since your imageGrayComp is not grayscale nor 8U, you cannot access its pixels with vec3b or uchar.

The problem is imageGrayClassify is not a grayscale image of image. You use .convertTo() which can convert e. g. a CV_32F-image to a CV_8U-image but not BGR to Gray. This call will convert the image to CV_64F because CV_BGR2GRAY == CV_64F == 6. All just macros and a typeunsafe interface.

You need

cv::cvtColor(image, imageGrayClassify, CV_BGR2GRAY);

then you shoud be able to access imgGrayComp with .at<uchar>(5, 4). Be aware that .at<Vec3b>(5, 4) is still wrong, because a grayscale-image has only one channel. Vec3b is normally used for a 3-channel 8-bit image.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top