Использование частного члена данных в реализации класса?

Привет это часть моего кода в библиотеке OpenCV. Infact у меня есть 2 вопроса.

1) я хочу инициализировать класс шаблона vector<Mat> Image[MAX_ITER]
где MAX_ITERconst static intреализовано в определении класса. При использовании a Image[r]как показано ниже в реализации класса для хранения изображений:

        ImageSegment::Image[r] = Mat::zeros(src.rows, src.cols, CV_8UC3);
        ImageSegment::Image[r] = tempMerged.reshape(0,src.rows);

выдает следующую ошибку.

 Invalid use of non-static data member 'Image'

2) у меня есть частный элемент данныхminCluster = 2, инициализированный в конструкторе, но при использовании minClusterдля инициализации другого члена данных в реализации класса:

    int clusters = ImageSegment::minCluster;

Я получаю следующую ошибку:

minCluster is a private member of 'ImageSegment'

Я понимаю, что я использую модификатор доступа publicДля minClusterв этом случае, чтобы исправить мою ошибку, но я не хочу, чтобы minCluster был изменен. Как мне это сделать?
Я предполагаю, что мое понимание модификаторов доступа не велико, и поэтому у меня есть эти проблемы.

Это определение класса:

#ifndef ____ImageSegment__
#define ____ImageSegment__

#include <stdio.h>
#include <opencv2/opencv.hpp>
#include <opencv2/video/background_segm.hpp>
#include <stdio.h>
#include <opencv2/opencv.hpp>
#include "math.h"
#include <opencv2/video/background_segm.hpp>

#endif /* defined(____ImageSegment__) */


using namespace cv;
using namespace std;

class ImageSegment
{
   private:
     Mat filterOutput, dst;
     Mat FG, BG;
     float area;
     CvPoint origin;
     Size filter;
     Mat detectEdges(Mat src);
     vector<Point>  approxOuterPolygon(Mat edge);
     vector<int> kmeansSegmentation(Mat src);
     int optimalCluster(vector<int> compactness, int iter, int minCluster);
     void displayImage(Mat src, vector<Point> approxPolygon);
     int minCluster;


  public:
    ImageSegment();
    CvPoint findSegment(Mat src);
    const static int MAX_ITER = 12;
    vector<Mat>Image[MAX_ITER];
};

Это часть реализации моего класса
Конструктор:

    ImageSegment::ImageSegment()
    {
          minCluster = 3;
          cout << "nImage segment obj createdn" << endl;
    }

Другая часть реализации класса

vector<int> kmeansSegmentation(Mat src)
{
//Now run K-Means algorithm to segment image based on colour
//Setup for K-Means Algorithm
Mat samples(src.rows*src.cols, src.channels(), CV_32F);
Mat srcClone;

//Algorithm will run 5 times with 5 cluster values, best compactness will be chosen
vector<int> compactness(ImageSegment::MAX_ITER);

vector<vector<int>> labels(samples.rows);
vector<Mat> centresVector(ImageSegment::MAX_ITER);
Mat centres;
int clusters = ImageSegment::minCluster;

//Building the samples into feature vector of RGB pixel values of src
srcClone = src.clone();
samples = srcClone.reshape(0,samples.rows);

//Convert to algorithm friendly CV_32F
samples.convertTo(samples, CV_32F);

//Run K-Means for MAX_ITER times
for (int clusterCount = 0; clusterCount < ImageSegment::MAX_ITER; clusterCount++)
{
    compactness[clusterCount] = kmeans(samples, clusters, labels[clusterCount], TermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 10, 1.0), 5, KMEANS_PP_CENTERS, centres);

    cout << "COM: " << compactness[clusterCount] << endl;

    //Increment cluster (k++)
    clusters++;
    centresVector[clusterCount] = centres;
}

//Reconstruct the processed image
vector<Mat> temp(3);
Mat tempMerged;
int *labelPtr;

//Reassign all of 'temp' to zeros
for (int q = 0; q < 3; q++)
{
    temp[q] = Mat::zeros(samples.rows, 1, CV_8UC1);
}

for (int r = 0; r < ImageSegment::MAX_ITER; r++)
{
    //Final output image is 3-channel dimension(src)
    ImageSegment::Image[r] = Mat::zeros(src.rows, src.cols, CV_8UC3);
    labelPtr = labels[r].data();
    centres = centresVector[r];

    for (int x = 0; x <= samples.rows; x++)
    {
        temp[0].at<float>(x,0) = centres.at<float>(*labelPtr,0);
        temp[1].at<float>(x,1) = centres.at<float>(*labelPtr,1);
        temp[2].at<float>(x,2) = centres.at<float>(*labelPtr,2);
        ++labelPtr;
    }

    tempMerged = Mat::zeros(src.rows, src.cols, src.type());
    merge(temp, tempMerged);
    ImageSegment::Image[r] = tempMerged.reshape(0,src.rows);
}

return compactness;

}

1 ответ

  1. Для 1), они синтаксис, который вы использовали, чтобы получить доступ к статическому члену, но изображение является нестатическим членом данных. Вместо этого вы создадите объект типа ImageSegment, а затем получите доступ к его элементу данных изображения:

    ImageSegment seg;
    seg.Image[r] = Mat::zeros(src.rows, src.cols, CV_8UC3);
    seg.Image[r] = tempMerged.reshape(0, src.rows);
    

    Для 2) общий шаблон кодирования заключается в том, чтобы поместить элемент данных в личное и использовать для него метод доступа:

    class ImageSegment {
     private:
      ...
      int minCluster_;  // note the trailing underscore
    
     public:
      ImageSegment();
      ...
      int minCluster() const { return minCluster_; }
      ...
    };
    

    Затем можно инициализировать другую переменную, например:

    ImageSegment seg;
    ... // do something about seg
    int clusters = seg.minCluster();