VideoCapture v;
MAT img;

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

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

VideoCapture v;
MAT img;

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

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

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