私は OpenCV C++ インターフェイスを頻繁に使用し、Mat をプライベート リソースとして使用する多くのクラスを設計しました。
最近、明示的にクローンを呼び出さない限り、常に画像データを共有リソースとして使用する Mat クラスが気になりました。私が書いたとしてもconst Mat
、画像データが後で外部から変更されないかどうかはわかりません。
したがって、カプセル化を確実にするためにクローンを作成する必要があります。しかし、Mat を明示的に複製する必要がある場合の問題は、多くの場合不要でコストがかかることです。一方、共有イメージデータの必要性は roi セレクターに由来し、次のようなものを記述できることを理解しています:
Mat m_small = m_big(my_roi)
.
私の質問は次のとおりです。
1.) cv::Mat クラスはかなり怠惰に複製されるべきではありませんか? そのため、ユーザーは外部から Mat を共有リソース ハンドラーとして見ることはありません。SharedMat
実際の共有イメージデータが必要な場合のように、ユーザーは何かと呼ばれるクラスを明示的にインスタンス化するべきではありませんか?
2.)クラスのプライベート リソースとして cv::Mat の場合、常にクローンを作成するよりも優れた戦略はありますか?
更新: 「Mat::clone()
データを変更する予定がない限り、使用しないでください。」(by Vadim Pisarevsky)
このアイデアには問題があります。
このクラスがある状況を考えてみましょう:
class Res_handler{
public:
const Mat emit_mat(){ return m_treasure; } // I argue you are compelled to clone here.
private:
Mat m_treasure;
};
この場合にそうでないclone
場合は、書くことができます
Mat m_pirate = res_handler.emit_mat(); m_pirate = Scalar(0,0,0);
と の間で共有される画像データを介して、m_treasure
内部で完全なブラックアウトが発生します。:) したがって、内部の偶発的な変更を避けるために、それが必要です。res_handler
m_pirate
m_treasure
m_treasure
clone
一方、このソリューションにも欠陥があります。
const Mat m_pirate = res_handler.emit_mat();
も変更される可能性があるためm_treasure
、 の内容がm_pirate
バックグラウンドで変更され、海賊のプログラマーにとって大きな頭痛の種になります。:)