OpenCV 3.4.1中Mat_<uchar>迭代器创建失败问题求助
Mat::begin() Hey there, let's break down why you're hitting that assertion error and how to fix it step by step.
The Root Cause
The error Assertion failed (elemSize() == sizeof(_Tp)) in cv::Mat::begin pops up because your binary Mat is a 3-channel image (elemSize = 3, meaning each pixel takes up 3 bytes), but you're trying to iterate over it with a Mat_<uchar>::const_iterator—which expects a single-channel image (each pixel is 1 byte, sizeof(uchar) = 1).
Looking at your getCorners function: if the input image is a color image (3-channel), all operations like dilate, erode, and absdiff will preserve that 3-channel structure. That means the returned result (your binary parameter) stays 3-channel, creating the mismatch when you try to use a single-channel iterator.
Solution 1: Make getCorners Return a Single-Channel Image
The cleanest fix is to ensure getCorners works with a grayscale image from the start. Convert the input to grayscale if it's color, so all subsequent operations produce a single-channel output.
Here's the updated getCorners code:
Mat getCorners(const Mat &image) { // Convert input to grayscale if it's a color image Mat gray; if (image.channels() == 3) { cvtColor(image, gray, COLOR_BGR2GRAY); } else { gray = image.clone(); } Mat result; dilate(gray, result, cross); erode(result, result, diamond); Mat result2; dilate(gray, result2, x); erode(result2, result2, square); absdiff(result2, result, result); applyThreshold(result); // Assuming this outputs a single-channel binary image return result; }
Solution 2: Adjust drawOnImage for 3-Channel binary (If Necessary)
If you need binary to stay 3-channel for some reason, adjust the iterator to match the 3-channel structure. For a 3-channel uchar image, each pixel is a Vec3b, so use that iterator type and check if all channels are 0 (since it's a binary map):
void drawOnImage(const cv::Mat& binary, Mat& image) { Mat_<Vec3b>::const_iterator it = binary.begin<Vec3b>(); Mat_<Vec3b>::const_iterator itend = binary.end<Vec3b>(); for (int i = 0; it != itend; ++it, ++i) { // Check if the pixel is black (all channels 0) in the binary map if ((*it)[0] == 0 && (*it)[1] == 0 && (*it)[2] == 0) { // Fixed coordinate calculation: use cols instead of step to avoid padding issues circle(image, Point(i % image.cols, i / image.cols), 5, Scalar(255, 0, 0)); } } }
Note: I also fixed the coordinate math—i%image.step is incorrect because step includes padding bytes. Using image.cols gives the correct horizontal position for the pixel.
Key Takeaway
Binary images for edge/corner detection are almost always single-channel, so Solution 1 is the standard, most maintainable approach. It aligns with common computer vision practices and avoids unnecessary complexity with multi-channel binary maps.
内容的提问来源于stack exchange,提问作者KJS_999

