【发布时间】:2011-04-20 13:53:08
【问题描述】:
我正在尝试使用 OpenCV 来查找图像中像素的 RGB 值。到目前为止,我已经尝试了以下方法:
int blue = ((uchar *)(img->imageData + y*img->widthStep))[x*img->nChannels + 0];
int green = ((uchar *)(img->imageData + y*img->widthStep))[x*img->nChannels + 1];
int red = ((uchar *)(img->imageData + y*img->widthStep))[x*img->nChannels + 2];
int blue = ((float *)(img->imageData + i*img->widthStep))[j*img->nChannels + 0];
int green = ((float *)(img->imageData + i*img->widthStep))[j*img->nChannels + 1];
int red = ((float *)(img->imageData + i*img->widthStep))[j*img->nChannels + 2];
CvPoint pt = {5,5};
uchar* temp_ptr = &((uchar*)(img->imageData + img->widthStep*pt.y))[pt.x*3];
int blue = temp_ptr[0];
int green = temp_ptr[1];
int red = temp_ptr[2];
但在上述所有情况下,我都会遇到同样的错误:
Unhandled exception at 0x00f5104f in test.exe: 0xC0000005: Access violation reading location: 0x00000048
最后一个十六进制数字 (0x0...48) 永远不会改变。我看起来这可能是由于写得比数组的边界更远。所以我在没有任何其他代码的情况下单独运行了每个示例,但仍然得到相同的错误。是什么导致了这个错误,我该如何解决?
额外信息:Windows 7、MSVC 2010 Express、OpenCV 2.1
--UPDATE--
我意识到上面的代码比它需要的更复杂,所以我以 karlphillip 提供的 sn-p(谢谢!)作为基础并使用了类似的方法。我仍然遇到错误,这次是在一个更陌生的地方:
IplImage *slice = cvLoadImage("test.png");
int bpp = slice ->nChannels;
错误发生在第二行,仍然是访问冲突。在此之前没有执行与 OpenCV 相关的代码,只是一些变量初始化。 'test.png' 只是一个 7*7 像素的 'X' 我在油漆中制作来测试它,使用 .jpg 有 hte saem 结果。
为了确保我没有错误地安装 OpenCV,我单独使用了这段代码(从下面复制):
int main ()
{
IplImage* pRGBImg = cvCreateImage(cvSize(5,5),IPL_DEPTH_8U,3);
int width = pRGBImg->width;
int height = pRGBImg->height;
int bpp = pRGBImg->nChannels;
cvNamedWindow("Image view", 1);
cvShowImage("Image view", pRGBImg);
cvWaitKey(0);
cvDestroyWindow("Image view");
for (int i=0; i < width*height*bpp; i+=bpp)
{
if (!(i % (width*bpp))) // print empty line for better readability
std::cout << std::endl;
std::cout << std::dec << "R:" << (int) pRGBImg->imageData[i] <<
" G:" << (int) pRGBImg->imageData[i+1] <<
" B:" << (int) pRGBImg->imageData[i+2] << " ";
}
}
这没有返回任何错误,但我确实得到了一些可能很奇怪的结果,这是控制台输出的前几行:
R:13 G:-16 B:-83
R:-70: G:13 B:-16
R:-83 G:-70 B: 13
负 RGB 值?这是可以预期的,还是这不起作用。如果正常,那么我正在加载的图像('test.png')一定是问题所在。但是,如果一个简单的频道数量请求导致访问冲突,我做错了什么?
【问题讨论】:
-
这些行中的哪一行实际上是违规的来源?这应该可以使用调试器检测到。
-
在前两个示例中,错误发生在第一行。第三次发生在第二次