0

在学习opencv的书中,第3章有一个问题:

Create a two dimensional matrix with three channels of type byte with data size 100-by-100 and initialize all the values to 0.

Use the pointer element to access cvptr2D to point to the middle 'green' channel.Draw the rectangle between 20,5 and 40,20.

我已经设法完成了第一部分,但我无法理解第二部分。这是我到目前为止所做的:

/*
    Create a two dimensional matrix with three channels of type byte with data size 100-    by-100 and initialize all the values to 0.
    Use the pointer element to access cvptr2D to point to the middle 'green' channel.Draw `enter code here`the rectangle between 20,5 and 40,20.
*/
void ex10_question3(){
    CvMat* m = cvCreateMat(100,100,CV_8UC3);
    CvSetZero(m);   // initialize to 0.
        uchar* ptr = cvPtr2D(m,0,1); // if RGB, then start from first RGB pair, Green.
    cvAdd(m,r); 
    cvRect r(20,5,20,15);
    //cvptr2d returns a pointer to a particular row element. 

}

我正在考虑同时添加矩形和矩阵,但显然这不起作用,因为矩形只是坐标和宽度/高度。我不熟悉 cvPtr2D()。我怎样才能想象练习要我做什么,谁能给我一个正确方向的提示?解决方案必须在 C 中。

根据我对交错 RGB 通道的理解,第二个通道将始终是感兴趣的通道。(数组索引:1,4,6..)

4

2 回答 2

1

那就是风吹来的方向...

首先,问题在于 C API。由于遗留原因,此 API 仍然存在,但很快就会过时。如果您对 OpenCV 很认真,请参阅 C++ API。官方教程是很好的信息来源。

为了进一步针对您的问题,这将是您在 C++ 中的问题的实现。

cv::Mat canvas = cv::Mat::zero(100,100, CV_8UC3); // create matrix of bytes, filled with 0
std::vector<cv::Mat> channels(3); // prepare storage for splitting
split(canvas, channels); // split matrix to single channels
rectangle(channels[1], ...); // draw rectangle [I don't remember exact params]
merge(channels, canvas); // merge the channels together

如果你只需要绘制绿色矩形,它实际上要容易得多:

cv::Mat canvas = cv::Mat::zero(100,100, CV_8UC3); // create matrix of bytes, filled with 0
rectangle(canvas, ..., Scalar(0,255,0)); // draw green rectangle 

编辑:

要了解如何使用 C++ API 访问图像中的单个像素,请参考以下答案: https ://stackoverflow.com/a/8139210/892914

于 2013-10-04T08:23:34.910 回答
0

试试这个代码:

    cout<<"Chapter 3. Task 3."<<'\n';
CvMat *Mat=cvCreateMat(100, 100, CV_8UC3);
cvZero(Mat);
for(int J=5; J<=20; J++)
    for(int I=20; I<40; I++)
        (*(cvPtr2D(Mat, J, I)+1))=(uchar)(255);
cvNamedWindow("Chapter 3. Task 3", CV_WINDOW_FREERATIO);
cvShowImage("Chapter 3. Task 3", Mat);
cvWaitKey(0);
cvReleaseMat(&Mat);
cvDestroyAllWindows;
于 2013-10-09T17:58:35.930 回答