Как мне индексировать через трехмерную матрицу? У меня есть этот код, и я знаю, что строка внутри циклов неверна. Любые предложения по правильному выполнению.

    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];
        }
    }
1
kuppy28 28 Май 2017 в 10:39

2 ответа

Лучший ответ

Ваш код сложен, но, насколько я понимаю, вам нравится знать, как получить доступ ко всем данным точки (т. е. ко всем 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<>. в вашем коде:

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;
0
Mokhabadi 28 Май 2017 в 12:15

В OpenCV документации говорится кое-что о 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;
-1
Andre Kampling 28 Май 2017 в 09:07