C++ Image Class based on OpenCV

class Image
{
    private:

        cv::Mat _mat;

        std::string _path;

        int _width    = 0;
        int _height   = 0;
        int _channels = 0;

    public:

        Image() {}

        void reset()
        {
            _mat.release();
            _path.clear();
            _width = _height = _channels = 0;
        }

        Image& operator=( const Image& img )
        {
            reset();

            _mat = img._mat.clone();

            _path     = img._path;
            _width    = img._width;
            _height   = img._height;
            _channels = img._channels;

            return (*this);
        }

        // RGB-order) k: 0=Red, 1=Green, 2=Blue
        unsigned char& operator()( int i, int j, int k=0 )
        {
            return _mat.data[ _channels * ( j*_width + i ) + (2-k) ];
        }

        const unsigned char& operator()( int i, int j, int k=0 ) const
        {
            return _mat.data[ _channels * ( j*_width + i ) + (2-k) ];
        }

        Image& create( int width, int height, int channels )
        {
            reset();

            _mat = cv::Mat::zeros( height, width, CV_MAKETYPE(CV_32F, channels ) ); // black image

            _width    = width;
            _height   = height;
            _channels = channels;

            return (*this);
        }

        int width() const
        {
            return _width;
        }

        int height() const
        {
            return _height;
        }

        int channels() const
        {
            return _channels;
        }

        cv::Size size() const
        {
            return cv::Size( _width, _height );
        }

        cv::Mat& mat()
        {
            return _mat;
        }

        const cv::Mat& mat() const
        {
            return _mat;
        }

        bool load( const std::string& path, bool asGrayScale=false )
        {
            if( _path == path ) { return true; } // same file handling

            reset();

            _path = path;

            if( asGrayScale ) { _mat = cv::imread( path.c_str(), cv::IMREAD_GRAYSCALE ); }
            else              { _mat = cv::imread( path.c_str(), cv::IMREAD_UNCHANGED ); }

            _width    = _mat.cols;
            _height   = _mat.rows;
            _channels = _mat.channels();

            if( (_channels==3) && asGrayScale ) { toGrayScale(); }

            return true;
        }

        void toGrayScale()
        {
            cv::Mat gray;

            if( _channels == 3 )
            {
                cvtColor( _mat, gray, cv::COLOR_BGR2GRAY );
                _channels = 1;
            }

            _mat = gray.clone();
        }
};

Leave a Reply