在类实现中使用私有数据成员?

时间:2016-12-31 15:30:00

标签: c++ opencv

您好,这是我在OpenCV库中的代码的一部分。事实上我有2个问题。

1)我想初始化vector<Mat> Image[MAX_ITER]的模板类 其中MAX_ITER是在类定义中实现的const static int。在类实现中使用如下所示的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 created\n" << 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 个答案:

答案 0 :(得分:0)

对于1),您使用的语法是访问静态成员,但Image是非静态数据成员。您将创建一个ImageSegment类型的对象,然后访问其Image数据成员:

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();