【问题标题】:How to access a 3 dimensional Matrix elements?如何访问 3 维矩阵元素?
【发布时间】:2017-05-28 07:39:07
【问题描述】:

如何通过 3 维矩阵进行索引? 我有这段代码,我知道循环内的字符串是错误的。有关以正确方式进行操作的任何建议。

    Mat frame_;
    cvtColor(frame, frame_, CV_BGR2HSV);
    int size[3] = { capture_box_dim*capture_box_count, capture_box_dim, 3};
    Mat ROI = Mat::zeros (3, size, frame_.type());
    for (int i = 0; i < capture_box_count; i++)
    {
        for (int j = i*capture_box_dim, int k = box_pos_y[i], int l = 0, int t = box_pos_x[i];
                j < i*capture_box_dim + capture_box_dim
             && k < box_pos_y[i] + capture_box_dim 
             && l < capture_box_dim
             && t < box_pos_x[i] + capture_box_dim;
             j++, k++, l++, t++)
        {
            ROI[j][l] = frame_[k][t];
        }
    }

【问题讨论】:

  • 代码不完整,3D数组在哪里?
  • “循环内的字符串”是什么意思?我在您的代码中没有看到任何字符串类型的变量。
  • 您的 for 循环看起来过于复杂。我会推荐一个更简单的布局。读起来很费劲。

标签: c++ opencv mat


【解决方案1】:

您的代码很复杂,但据我了解,您想知道如何访问一个点的所有数据(即所有 3 个值)。使用Vec 很简单。

Vec3b intensity = img.at<Vec3b>(y, x);
uchar blue = intensity.val[0];
uchar green = intensity.val[1];
uchar red = intensity.val[2];

访问 Mat 元素的最佳方法是 at&lt;&gt; 方法。在您的代码中:

ROI.at<Vec3b>(j,l) = frame_.at<Vec3b>(k,t);

Vec 是 Vector 类。 Vec后面的数字表示通道数。例如,如果您有一个 RGB 图像,那么您有 3 个通道。最后一个字符表示类型。最常见的向量是Vec3b。这里定义了向量的类型:

typedef Vec<uchar, 2> Vec2b;
typedef Vec<uchar, 3> Vec3b;
typedef Vec<uchar, 4> Vec4b;

typedef Vec<short, 2> Vec2s;
typedef Vec<short, 3> Vec3s;
typedef Vec<short, 4> Vec4s;

typedef Vec<int, 2> Vec2i;
typedef Vec<int, 3> Vec3i;
typedef Vec<int, 4> Vec4i;

typedef Vec<float, 2> Vec2f;
typedef Vec<float, 3> Vec3f;
typedef Vec<float, 4> Vec4f;
typedef Vec<float, 6> Vec6f;

typedef Vec<double, 2> Vec2d;
typedef Vec<double, 3> Vec3d;
typedef Vec<double, 4> Vec4d;
typedef Vec<double, 6> Vec6d;

【讨论】:

    【解决方案2】:

    OpenCV 文档中提到了 3D。 还有一个带有 3D 直方图的示例:

    void computeNormalizedColorHist(const Mat& image, Mat& hist, int N, double minProb)
    {
        const int histSize[] = {N, N, N};
    
        // make sure that the histogram has a proper size and type
        hist.create(3, histSize, CV_32F);
    
        // and clear it
        hist = Scalar(0);
    
        // the loop below assumes that the image
        // is a 8-bit 3-channel. check it.
        CV_Assert(image.type() == CV_8UC3);
        MatConstIterator_<Vec3b> it = image.begin<Vec3b>(),
                                 it_end = image.end<Vec3b>();
        for( ; it != it_end; ++it )
        {
            const Vec3b& pix = *it;
            hist.at<float>(pix[0]*N/256, pix[1]*N/256, pix[2]*N/256) += 1.f;
        }
    
        minProb *= image.rows*image.cols;
    
        // intialize iterator (the style is different from STL).
        // after initialization the iterator will contain
        // the number of slices or planes the iterator will go through.
        // it simultaneously increments iterators for several matrices
        // supplied as a null terminated list of pointers
        const Mat* arrays[] = {&hist, 0};
        Mat planes[1];
        NAryMatIterator itNAry(arrays, planes, 1);
        double s = 0;
        // iterate through the matrix. on each iteration
        // itNAry.planes[i] (of type Mat) will be set to the current plane
        // of the i-th n-dim matrix passed to the iterator constructor.
        for(int p = 0; p < itNAry.nplanes; p++, ++itNAry)
        {
            threshold(itNAry.planes[0], itNAry.planes[0], minProb, 0, THRESH_TOZERO);
            s += sum(itNAry.planes[0])[0];
        }
    
        s = 1./s;
        itNAry = NAryMatIterator(arrays, planes, 1);
        for(int p = 0; p < itNAry.nplanes; p++, ++itNAry)
            itNAry.planes[0] *= s;
    }
    

    我认为这对你来说是重要的代码行:

    hist.at<float>(pix[0]*N/256, pix[1]*N/256, pix[2]*N/256) += 1.f;
    

    【讨论】:

    • 当 OP 根本没有询问直方图时,为什么还要包含直方图的代码?实际上,该示例确实提取了一个包含每个颜色通道值的 Vec3b,但您突出显示的行没有显示 pix 是什么数据类型以及为什么会这样访问它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-13
    • 1970-01-01
    • 2022-10-24
    • 1970-01-01
    • 2023-04-05
    • 2021-12-30
    相关资源
    最近更新 更多