在读取了未知深度和信道数的图像后,我想逐一访问它的像素。
在opencv 1.x上,代码如下:
IplImage * I = cvLoadImage( "myimage.tif" );
CvScalar pixel = cvGet2D( I, y, x );但是在OpenCV2.x上,cv::Mat.at()方法要求我知道图像的类型:
cv::Mat I = cv::imread( "myimage.tif" );
if( I.depth() == CV_8U && I.channels() == 3 )
cv::Vec3b pixel = I.at<cv::Vec3b>( x, y );
else if( I.depth() == CV_32F && I.channels() == 1 )
float pixel = I.at<cv::float>( x, y );是否有一个类似于cvGet2D的函数可以在编译时接收cv::Mat并返回cv::Scalar而不知道图像的类型?
发布于 2014-10-31 22:14:13
对于C++的初学者来说.
...和/或一个只需要节省几秒钟代码输入就能完成 http://en.wikipedia.org/wiki/%C3%89variste_Galois的黑客
cv::Mat mat = ...; // something
cv::Scalar value = cv::mean(mat(cv::Rect(x, y, 1, 1)));(免责声明:这段代码的浪费程度仅略低于为革命事业而死的年轻人。)
发布于 2013-10-22 08:14:10
简短的回答是否定的。在C++ API中没有这样的函数。
这背后的理由是性能。cv::Scalar (和CvScalar)和cv::Vec<double,4>是一样的。因此,对于除CV_64FC4以外的任何CV_64FC4类型,都需要进行转换才能获得cv::Scalar。此外,这个方法将是一个巨大的switch,就像在您的示例中(您只有两个分支)。
但是我想这个函数通常是很方便的,所以为什么不使用它呢?我的猜测是,人们会过度使用它,从而导致他们的算法性能非常差。因此,为了强制客户端代码使用静态类型的方法,OpenCV使得访问单个像素变得非常不方便。这并不是一件很方便的事情,因为通常情况下,你实际上是静态地知道这种类型的,从性能上来说,这是一个非常大的问题。所以,我认为这是一个很好的交换。
发布于 2013-10-22 14:41:24
我也有同样的问题,我只是想快速测试一些东西,而性能不是问题。但是代码的所有部分都使用cv::Mat()。我所做的是
Mat img; // My input mat, initialized elsewhere
// Pretty fast operation, Will only create an iplHeader pointing to the data in the mat
// No data is copied and no memory is mallocated.
// The Header resides on the stack (note its type is "IplImage" not "IplImage*")
IplImage iplImg = (IplImage)img;
// Then you may use the old (slow converting) legacy-functions if you like
CvScalar s = cvGet2D( &iplImg, y, x );https://stackoverflow.com/questions/19501805
复制相似问题