OpenCV 2.0 – cv::Ptr
A template class for smart reference-counting pointers
OpenCV 2.0では cv::Ptr という参照カウント方式のスマートポインタが用意されています。
これは Boost C++ Library の shared_ptr と同様のもので大変便利です。
参考:参照カウント – Wikipedia
一時的にcv::Ptrクラスのrefcountというメンバをprotectedからpublicに変更して挙動を見てみます。
(cxcore.hppの660行目付近にあります)
class Test {
public:
Test() { std::cout<<"construct"<<std::endl; }
~Test() { std::cout<<"destruct"<<std::endl; }
};
int main(void) {
using namespace std;
cv::Ptr<Test> p1(new Test()); // 参照カウント 1
cout<<"refcount: "<<*(p1.refcount)<<endl;
{
cv::Ptr<Test> p2;
p2 = p1; // 参照カウントが+1されて2になる
cout<<"refcount: "<<*(p1.refcount)<<endl;
} // 参照カウントが-1されて1になる、まだオブジェクトは解放されない
cout<<"refcount: "<<*(p1.refcount)<<endl;
cout<<"main exit"<<endl;
return 0;
} // Testオブジェクトが解放される
--------------
/** 結果
construct
refcount: 1
refcount: 2
refcount: 1
main exit
destruct
**/
すばらしい。
また、IplImage に適用した場合はきちんとテンプレートの特殊化が施されているので安心です。
int main(void) {
cv::Ptr<IplImage> img = cvLoadImage("test.jpg");
if(img.empty()) {
std::cerr<<"can't load image."<<std::endl;
return -1;
}
namedWindow("image", CV_WINDOW_AUTOSIZE);
imshow("image", Mat(img));
waitKey();
return 0;
}
--------------------------------------------------------------------
/* 参照カウント(refcount)が0になると Ptr::delete_obj() が呼ばれる
CvMatやIplImageは以下のように特殊化されている */
template<> inline void Ptr<CvMat>::delete_obj()
{ cvReleaseMat(&obj); }
template<> inline void Ptr<IplImage>::delete_obj()
{ cvReleaseImage(&obj); }
OpenCV 1.0ではメモリのアロケートに cvAlloc() という malloc() のラッパーが使われていましたが、
OpenCV 2.0ではその代わりに fastMalloc() という関数が用意され、cv::Ptr内でもコールされています。
少し中を覗いてみると、どうやらシステムコールの mmap() でアロケートしているようです。
(Windowsでは普通のmalloc()が呼ばれる模様)
詳しくはまだ読めていませんが、fastというくらいだからきっと速くなっているんでしょう。
メモリ管理を cv::Ptr に任せておくと開発が楽になるのは間違いなさそうです。
関連記事:
OpenCV 2.0を試してみた


Comments
No comments so far.