【问题标题】:divide image to regions , assign them labels? use pointers将图像划分为区域,为它们分配标签?使用指针
【发布时间】:2017-03-19 07:51:08
【问题描述】:

我有一个图像,假设是 800x800 像素,我想定义 200x200 像素的区域并能够处理它们。

我不知道如何进行这项工作。 我试过了:

int N = 4;
Size smallSize( graySize.width / N ,graySize.height / N );

Mat region_frame;
vector<Mat> smallImages;

namedWindow( "Display window", WINDOW_AUTOSIZE );
for( int i = 0; i < graySize.height - N; i+= smallSize.height )
{
    for( int j = 0; j < graySize.width - N; j+= smallSize.width )
    {
        Rect rect = Rect( j,i, smallSize.width, smallSize.height );
        region_frame = grayImg( rect );
        smallImages.push_back( region_frame.clone() ); 

        imshow( "Display window", region_frame );           
        waitKey(0);


    }
}

但我没有收到任何输出(没有创建任何窗口!)。 如果我对 grayImg 使用 imshow ,它会正确显示。

另外,因为我想处理这些块/区域/子图像,有没有办法给它们分配标签? 例如 region[0] ( 它将包含像素 0-199 x 0-199 , region[1] 200-399 x 200-399 等等。

*********编辑****************

所以,不显示图像的问题是我上面的代码:

if( grayImg.isContinuous() )
{
    graySize.width *= graySize.height;
    graySize.height = 1;
}

去掉那个,图片就可以正常显示了!

现在,仍然是处理 smallImages 以便能够进行计算。

例如,我可以做一个 Mat 对象

float *theData = (float*)grayImg.data;

但是对于像 smallImages 这样的vector&lt;Mat&gt;? 如何使用指针?

【问题讨论】:

  • 发生了什么?我刚刚测试了它,它正在工作......
  • @Berriel:它只是不产生任何输出。它的行为就像没有调用 imshow。但是,如果我将 imshow 用于原始图像(循环外),它会正确显示。
  • @Miki:我看到了这篇文章并且已经使用了“正确”的代码,即使这篇文章没有被接受的答案。另外,我在最后一段中问了一些其他问题。
  • 所以你想要一个每个区域都有相同标签的“标签”图像?
  • 我只是复制粘贴你的代码,添加了imread,它正在工作......关于你的最后一段:smallImages 将是一个区域向量,所以你可以使用@ 987654327@随你所愿

标签: c++ opencv


【解决方案1】:

如果您将每个子图像存储到smallImages 中而不进行克隆:

// Creates a new Mat header that "points" to the subimage
smallImages.push_back(grayImg(rect));

您可以像往常一样直接将子图像访问到主图像中,例如:

// Change the 3-rd subimage to be all 127
smallImages[2].setTo(127);

或使用指针(以下代码中的示例)。

示例代码:

#include <opencv2\opencv.hpp>
#include <vector>
using namespace std;
using namespace cv;

int main()
{
    Mat3b img = imread("D:\\SO\\img\\nice.jpg");
    resize(img, img, Size(800, 800));

    Mat grayImg;
    cvtColor(img, grayImg, COLOR_BGR2GRAY);
    grayImg.convertTo(grayImg, CV_32F);

    int N = 4;

    if (((grayImg.rows % N) != 0) || ((grayImg.cols % N) != 0))
    {
        // Error
        return -1;
    }

    Size graySize = grayImg.size();
    Size smallSize(grayImg.cols / N, grayImg.rows / N);

    vector<Mat> smallImages;

    for (int i = 0; i < graySize.height; i += smallSize.height)
    {
        for (int j = 0; j < graySize.width; j += smallSize.width)
        {
            Rect rect = Rect(j, i, smallSize.width, smallSize.height);
            smallImages.push_back(grayImg(rect));

            //imshow("Display window", grayImg(rect));
            //waitKey(0);
        }
    }

    // Change the 3-rd subimage to be all 127
    smallImages[2].setTo(127);

    // Iterate on all pixels in 2-nd subimage (will change also the main image)
    int idx_smallimage = 1;

    float* pdata = (float*)smallImages[idx_smallimage].data;
    int step = smallImages[idx_smallimage].step1();

    for (int i = 0; i < smallSize.height; ++i)
    {
        for (int j = 0; j < smallSize.width; ++j)
        {
            // Assign a random value to pixel (i,j) in subimage
            pdata[i * step + j] = rand() & 255;
            //smallImages[idx_smallimage](i * smallSize.width + j) = rand()&255;
        }
    }

    return 0;
}

【讨论】:

  • 通过说标签,我的意思是能够在每个子图像中工作。所以,我必须使用smallImages' for that .Can you please let me know how can I handle the smallImages` 作为指针?因为对于 Mat 对象我可以做到float *theData = (float*)grayImg.data;。但是对于像smallImages 这样的vector&lt;Mat&gt;
  • @George 改变了答案。告诉我
  • 我该怎么做:smallImages[ i*smallSize.width+j ] 。谢谢!
  • @George 再次检查...让我知道
  • :这工作正常,但正如我告诉你的,我怎样才能使用指针而不是 smallImages?例如 cout &lt;&lt; smallImages[idx_smallimage](i * smallSize.width + j) 不起作用。非常感谢您的帮助!
【解决方案2】:

你可以测试我已经实现的代码。也许你会根据你的需要改变它。

#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

using namespace cv;
using namespace std;

class ImageCells
{
public:
    ImageCells(int rows, int cols, int width, int height);
    virtual ~ImageCells() {}

    int cellwidth() const {return m_width;}
    int cellheight() const { return m_height;}
    int cols() const { return m_cols;}
    int rows() const { return m_rows;}

    void setCell( int col, int row, Mat img );
    void setImage( Mat img );
    Mat getCell( int col, int row );
    Mat image;

protected:
    int  m_width;
    int  m_height;
    int  m_cols;
    int  m_rows;
};

ImageCells::ImageCells( int rows, int cols, int width, int height)
{
    image = Mat::zeros( rows * height, cols * width, CV_8UC3);
    m_width = width;
    m_height = height;
    m_cols = cols;
    m_rows = rows;
}

void ImageCells::setCell( int col, int row, Mat img )
{
    if(img.cols == m_width & img.rows == m_height)
    {
        Mat roi = image( Rect(col * m_width, row * m_height, m_width, m_height) );
        img.copyTo(roi);
    }
}

Mat ImageCells::getCell( int col, int row )
{
    Mat roi = image( Rect(col * m_width, row * m_height, m_width, m_height) );
    return roi.clone();
}

void ImageCells::setImage( Mat img )
{
    if(img.cols >= image.cols & img.rows >= image.rows)
    img.copyTo(image);
}

int main( int argc, char** argv )
{
    ImageCells cells(4,3,70,90); // it creates a ImageCells class having 4 rows and 3 cols, cell witdh = 70 cell height = 90 you can change these values according your needs

    Mat img = Mat( 90, 70, CV_8UC3,Scalar(0,0,255)); // a test mat to use with cells.setCell important note is : img witdh&height must be same to cell witdh&height

for(int i=0; i < cells.cols(); i++)
    for(int j =0; j < cells.rows(); j++ )
{
   cells.setCell(i,j,img); // here you see how to use  setCell
   randu(img,30*i,160*j); // to show purpose changes img
   imshow("cells.image",cells.image);
   waitKey();
}

for(int i=0; i < cells.cols(); i++)
    for(int j =0; j < cells.rows(); j++ )
{
    imshow("cells",cells.getCell(i,j)); // here you see how to use  getCell
    waitKey();
}
    return 0;
}

【讨论】:

    猜你喜欢
    • 2011-11-04
    • 1970-01-01
    • 2015-05-21
    • 2013-10-07
    • 2018-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多