35863

[code]

    VideoCapture v;
    MAT img;
    
    v = VideoCapture(...);
    for ( ; ; )
    {
        v.read(img);    // またはv >> img;
        ・
        ・
        // 処理
        ・
        ・
        ・
    }
    
[/code]

OpenCV3.2で自動変数としてMATクラスを定義し上記の様な処理をループ内で繰り返し実行する場合、  
使いまわされる`img`は下記の様にリソース解放処理を実行するべきでしょうか？  
それとも`read`メソッド内で更新される時、一旦`release`してから上書きするのでしょうか。

[code]

    VideoCapture v;
    MAT img;
    
    v = VideoCapture(...);
    for ( ; ; )
    {
        img.release();
        v.read(img);    // またはv >> img;
        ・
        ・
        // 処理
        ・
        ・
        ・
    }
    
[/code]

自分なりにソースを追ってみようとしたのですが、力不足で`copyTo`あたりから追いきれなくなりました。ご存じの方がいらっしゃればご教授お願い致します。

[code]

    bool VideoCapture::read(OutputArray image)
    {
        CV_INSTRUMENT_REGION()
    
        if(grab())
            retrieve(image);
        else
            image.release();
        return !image.empty();
    }
    
    bool VideoCapture::retrieve(OutputArray image, int channel)
    {
        CV_INSTRUMENT_REGION()
    
        if (!icap.empty())
            return icap->retrieveFrame(channel, image);
    
        IplImage* _img = cvRetrieveFrame(cap, channel);
        if( !_img )
        {
            image.release();
            return false;
        }
        if(_img->origin == IPL_ORIGIN_TL)
            cv::cvarrToMat(_img).copyTo(image);
        else
        {
            Mat temp = cv::cvarrToMat(_img);
            flip(temp, image, 0);
        }
        return true;
    }
    
    void Mat::copyTo( OutputArray _dst ) const
    {
        CV_INSTRUMENT_REGION()
    
        int dtype = _dst.type();
        if( _dst.fixedType() && dtype != type() )
        {
            CV_Assert( channels() == CV_MAT_CN(dtype) );
            convertTo( _dst, dtype );
            return;
        }
    
        if( _dst.isUMat() )
        {
            if( empty() )
            {
                _dst.release();
                return;
            }
            _dst.create( dims, size.p, type() );
            UMat dst = _dst.getUMat();
    
            size_t i, sz[CV_MAX_DIM], dstofs[CV_MAX_DIM], esz = elemSize();
            for( i = 0; i < (size_t)dims; i++ )
                sz[i] = size.p[i];
            sz[dims-1] *= esz;
            dst.ndoffset(dstofs);
            dstofs[dims-1] *= esz;
            dst.u->currAllocator->upload(dst.u, data, dims, sz, dstofs, dst.step.p, step.p);
            return;
        }
    
        if( dims <= 2 )
        {
            _dst.create( rows, cols, type() );
            Mat dst = _dst.getMat();
            if( data == dst.data )
                return;
    
            if( rows > 0 && cols > 0 )
            {
                // For some cases (with vector) dst.size != src.size, so force to column-based form
                // It prevents memory corruption in case of column-based src
                if (_dst.isVector())
                    dst = dst.reshape(0, (int)dst.total());
    
                const uchar* sptr = data;
                uchar* dptr = dst.data;
    
                CV_IPP_RUN(
                        (size_t)cols*elemSize() <= (size_t)INT_MAX &&
                        (size_t)step <= (size_t)INT_MAX &&
                        (size_t)dst.step <= (size_t)INT_MAX
                        ,
                        CV_INSTRUMENT_FUN_IPP(ippiCopy_8u_C1R, sptr, (int)step, dptr, (int)dst.step, ippiSize((int)(cols*elemSize()), rows)) >= 0
                )
    
                Size sz = getContinuousSize(*this, dst);
                size_t len = sz.width*elemSize();
    
                for( ; sz.height--; sptr += step, dptr += dst.step )
                    memcpy( dptr, sptr, len );
            }
            return;
        }
    
        _dst.create( dims, size, type() );
        Mat dst = _dst.getMat();
        if( data == dst.data )
            return;
    
        if( total() != 0 )
        {
            const Mat* arrays[] = { this, &dst };
            uchar* ptrs[2];
            NAryMatIterator it(arrays, ptrs, 2);
            size_t sz = it.size*elemSize();
    
            for( size_t i = 0; i < it.nplanes; i++, ++it )
                memcpy(ptrs[1], ptrs[0], sz);
        }
    }
    
[/code]


CC BY-SA 3.0
2017-06-23T16:22:53.817
35842
2018-08-28T02:00:42.200
2017-06-24T22:40:41.920
21092
20931
question
c++ opencv
OpenCVのVideoCaptureのreadメソッドで取得したデータの解放について


あともう一歩、`Mat::copyTo`の中で呼び出している[`_dst.create()`](https://github.com/opencv/opencv/blob/a065e4b9aa119d1e3104800f0f9ef79ec8f1b73e/modules/core/src/matrix.cpp#L384-L409)が

[code]

    void Mat::create(int d, const int* _sizes, int _type)
    {
        int i;
        CV_Assert(0 <= d && d <= CV_MAX_DIM && _sizes);
        _type = CV_MAT_TYPE(_type);
    
        if( data && (d == dims || (d == 1 && dims <= 2)) && _type == type() )
        {
            if( d == 2 && rows == _sizes[0] && cols == _sizes[1] )
                return;
            for( i = 0; i < d; i++ )
                if( size[i] != _sizes[i] )
                    break;
            if( i == d && (d > 1 || size[1] == 1))
                return;
        }
    
        int _sizes_backup[CV_MAX_DIM]; // #5991
        if (_sizes == (this->size.p))
        {
            for(i = 0; i < d; i++ )
                _sizes_backup[i] = _sizes[i];
            _sizes = _sizes_backup;
        }
    
        release();
    
[/code]

とサイズが一致する場合は流用し、一致しない場合は`release()`してから確保しています。


CC BY-SA 3.0
2017-06-24T23:06:23.167
35863
2017-06-24T23:06:23.167
4236
35842
answer