Skip to content

Commit

Permalink
Remove copies in image and video implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
luisremis committed May 3, 2019
1 parent b2df45f commit 48bd510
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 37 deletions.
18 changes: 16 additions & 2 deletions include/vcl/Image.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ namespace VCL {
*/
Image(const cv::Mat &cv_img);

Image(cv::Mat &cv_img);

/**
* Creates an Image object from an encoded buffer
*
Expand All @@ -112,11 +114,21 @@ namespace VCL {

/**
* Creates a new Image object from an existing Image object
* This will make a deep copy of the arrays.
*
* @param img An existing Image object
*/
Image(const Image &img);

/**
* Move constructor, needed to avoid copies of the arrays.
* noexcept is needed to let vectors grow and call the move
* instead of copy constructor.
*
* @param img An existing Image object
*/
Image(const Image &&img) noexcept;

/**
* Sets an Image object equal to another Image object
*
Expand Down Expand Up @@ -173,14 +185,16 @@ namespace VCL {
* y coordinate, height, width)
* @return A new Image object that is only the requested area
*/
Image get_area(const Rectangle &roi) const;
Image get_area(const Rectangle &roi);

/**
* Gets an OpenCV Mat that contains the image data
*
* @param copy Specify if a deep copy of the cvmat will be made before
* returning the cvmat object.
* @return An OpenCV Mat
*/
cv::Mat get_cvmat() const;
cv::Mat get_cvmat(bool copy=false);

/**
* Gets the raw image data
Expand Down
26 changes: 20 additions & 6 deletions src/vcl/Image.cc
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,15 @@ Image::Image(const cv::Mat &cv_img)

}

Image::Image(cv::Mat &cv_img)
{
if ( cv_img.empty() ) {
throw VCLException(ObjectEmpty, "Image object is empty");
}

_image = new ImageData(cv_img);
}

Image::Image(void* buffer, long size, int flags)
{
cv::Mat raw_data(cv::Size(size, 1), CV_8UC1, buffer);
Expand All @@ -77,21 +86,23 @@ Image::Image(const Image &img)
_image = new ImageData(*img._image);
}

Image::Image(const Image &&img) noexcept
{
_image = new ImageData(*img._image, false);
}

void Image::operator=(const Image &img)
{
ImageData *temp = _image;
_image = new ImageData(*img._image);
delete temp;
}


Image::~Image()
{
delete _image;
}



/* *********************** */
/* GET FUNCTIONS */
/* *********************** */
Expand Down Expand Up @@ -122,19 +133,22 @@ int Image::get_image_type() const
}


Image Image::get_area(const Rectangle &roi) const
Image Image::get_area(const Rectangle &roi)
{
Image img_copy(*this);
*(img_copy._image) = _image->get_area(roi);

return img_copy;
}

cv::Mat Image::get_cvmat() const
cv::Mat Image::get_cvmat(bool copy)
{
cv::Mat mat = _image->get_cvmat();

return mat.clone();
if (copy)
return mat.clone();
else
return mat;
}

void Image::get_raw_data(void* buffer, long buffer_size ) const
Expand Down
78 changes: 56 additions & 22 deletions src/vcl/ImageData.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@

#include "ImageData.h"


using namespace VCL;

/* *********************** */
Expand All @@ -45,6 +44,7 @@ using namespace VCL;
/* *********************** */
/* READ OPERATION */
/* *********************** */

ImageData::Read::Read(const std::string& filename, Image::Format format)
: Operation(format),
_fullpath(filename)
Expand All @@ -64,7 +64,8 @@ void ImageData::Read::operator()(ImageData *img)
img->_channels = img->_tdb->get_image_channels();
}
else {
img->copy_cv(cv::imread(_fullpath, cv::IMREAD_ANYCOLOR));
auto img_read = cv::imread(_fullpath, cv::IMREAD_ANYCOLOR);
img->shallow_copy_cv(img_read);
if ( img->_cv_img.empty() )
throw VCLException(ObjectEmpty, _fullpath + " could not be read, \
object is empty");
Expand All @@ -74,6 +75,7 @@ void ImageData::Read::operator()(ImageData *img)
/* *********************** */
/* WRITE OPERATION */
/* *********************** */

ImageData::Write::Write(const std::string& filename, Image::Format format,
Image::Format old_format, bool metadata)
: Operation(format),
Expand Down Expand Up @@ -128,7 +130,7 @@ void ImageData::Resize::operator()(ImageData *img)
if ( !img->_cv_img.empty() ) {
cv::Mat cv_resized;
cv::resize(img->_cv_img, cv_resized, cv::Size(_rect.width, _rect.height));
img->copy_cv(cv_resized);
img->shallow_copy_cv(cv_resized);
}
else
throw VCLException(ObjectEmpty, "Image object is empty");
Expand All @@ -152,7 +154,7 @@ void ImageData::Crop::operator()(ImageData *img)
if ( img->_cv_img.rows < _rect.height + _rect.y || img->_cv_img.cols < _rect.width + _rect.x )
throw VCLException(SizeMismatch, "Requested area is not within the image");
cv::Mat roi_img(img->_cv_img, _rect);
img->copy_cv(roi_img);
img->shallow_copy_cv(roi_img);
}
else
throw VCLException(ObjectEmpty, "Image object is empty");
Expand Down Expand Up @@ -192,7 +194,7 @@ void ImageData::Flip::operator()(ImageData *img)
cv::Mat dst = cv::Mat(img->_cv_img.rows, img->_cv_img.cols,
img->_cv_img.type());
cv::flip(img->_cv_img, dst, _code);
img->_cv_img = dst.clone();
img->shallow_copy_cv(dst);
}
else
throw VCLException(ObjectEmpty, "Image object is empty");
Expand Down Expand Up @@ -239,7 +241,7 @@ void ImageData::Rotate::operator()(ImageData *img)

cv::Mat dst;
cv::warpAffine(img->_cv_img, dst, r, bbox.size());
img->_cv_img = dst.clone();
img->shallow_copy_cv(dst);
}
}
else
Expand Down Expand Up @@ -271,7 +273,18 @@ ImageData::ImageData()

ImageData::ImageData(const cv::Mat &cv_img)
{
copy_cv(cv_img);
deep_copy_cv(cv_img);

_format = Image::Format::NONE_IMAGE;
_compress = CompressionType::LZ4;
_image_id = "";

_tdb = NULL;
}

ImageData::ImageData(cv::Mat &cv_img)
{
shallow_copy_cv(cv_img);

_format = Image::Format::NONE_IMAGE;
_compress = CompressionType::LZ4;
Expand Down Expand Up @@ -300,7 +313,6 @@ ImageData::ImageData(const std::string &image_id)
}
else
_tdb = NULL;

}

ImageData::ImageData(void* buffer, cv::Size dimensions, int cv_type)
Expand All @@ -318,26 +330,34 @@ ImageData::ImageData(void* buffer, cv::Size dimensions, int cv_type)
_tdb->set_compression(_compress);
}

ImageData::ImageData(const ImageData &img)
ImageData::ImageData(const ImageData &img, bool copy)
{
_format = img._format;
_compress = img._compress;
_image_id = img._image_id;

if ( !(img._cv_img).empty() )
copy_cv(img._cv_img);
if ( !(img._cv_img).empty() ) {
if (copy) {
deep_copy_cv(img._cv_img);
}
else {
shallow_copy_cv(img._cv_img);
}
}

if ( img._tdb != NULL )
_tdb = new TDBImage(*img._tdb);
else
_tdb = NULL;

int start;
// TODO IS THIS REALLY NEEDED????
if ( img._operations.size() > 0 ) {
std::shared_ptr<Operation> front = img._operations.front();
if (front->get_type() == OperationType::READ) {
start = 1;
copy_cv(cv::imread(img._image_id, cv::IMREAD_ANYCOLOR));
cv::Mat img_read = cv::imread(img._image_id, cv::IMREAD_ANYCOLOR);
shallow_copy_cv(img_read);
}
else
start = 0;
Expand All @@ -352,7 +372,7 @@ void ImageData::operator=(const ImageData &img)
TDBImage *temp = _tdb;

if ( !(img._cv_img).empty() )
copy_cv(img._cv_img);
deep_copy_cv(img._cv_img);
else {
_channels = img._channels;

Expand Down Expand Up @@ -381,7 +401,8 @@ void ImageData::operator=(const ImageData &img)
std::shared_ptr<Operation> front = img._operations.front();
if (front->get_type() == OperationType::READ) {
start = 1;
copy_cv(cv::imread(img._image_id, cv::IMREAD_ANYCOLOR));
cv::Mat img_read = cv::imread(img._image_id, cv::IMREAD_ANYCOLOR);
shallow_copy_cv(img_read);
}
else
start = 0;
Expand Down Expand Up @@ -545,8 +566,10 @@ std::vector<unsigned char> ImageData::get_encoded(Image::Format format,
if ( _cv_img.empty() ) {
if ( _tdb == NULL)
throw VCLException(ObjectEmpty, "No data to encode");
else
copy_cv(_tdb->get_cvmat());
else {
cv::Mat img = _tdb->get_cvmat();
shallow_copy_cv(img);
}
}

std::vector<unsigned char> buffer;
Expand Down Expand Up @@ -653,7 +676,8 @@ void ImageData::set_data_from_raw(void* buffer, long size)

void ImageData::set_data_from_encoded(const std::vector<unsigned char> &buffer)
{
copy_cv(cv::imdecode(buffer, cv::IMREAD_ANYCOLOR));
cv::Mat img_read = cv::imdecode(buffer, cv::IMREAD_ANYCOLOR);
shallow_copy_cv(img_read);
}

void ImageData::set_minimum(int dimension)
Expand All @@ -666,7 +690,6 @@ void ImageData::set_minimum(int dimension)
}
}


/* *********************** */
/* IMAGEDATA INTERACTION */
/* *********************** */
Expand Down Expand Up @@ -752,16 +775,28 @@ void ImageData::delete_object()
/* COPY FUNCTIONS */
/* *********************** */

void ImageData::copy_cv(const cv::Mat &cv_img)
void ImageData::deep_copy_cv(const cv::Mat &cv_img)
{
_channels = cv_img.channels();

_height = cv_img.rows;
_width = cv_img.cols;

_cv_type = cv_img.type();

_cv_img = cv_img.clone(); // deep copy
}

void ImageData::shallow_copy_cv(const cv::Mat &cv_img)
{
_channels = cv_img.channels();

_height = cv_img.rows;
_width = cv_img.cols;
_width = cv_img.cols;

_cv_type = cv_img.type();

_cv_img = cv_img.clone();
_cv_img = cv_img; // shallow copy
}

template <class T>
Expand Down Expand Up @@ -819,4 +854,3 @@ std::string ImageData::create_fullpath(const std::string &filename,
else
return filename + "." + ext;
}

Loading

0 comments on commit 48bd510

Please sign in to comment.