Ask Your Question

Revision history [back]

void hwc_to_chw(cv::InputArray src, cv::OutputArray dst) {                      
  const int src_h = src.rows();                                                 
  const int src_w = src.cols();                                                 
  const int src_c = src.channels();                                             

  cv::Mat hw_c = src.getMat().reshape(1, src_h * src_w);                        

  cv::transpose(hw_c, dst);                                                        
  dst.assign(dst.getMat().reshape(1, {src_c, src_h, src_w}));                      
}

// Max channels is currently 512
void chw_to_hwc(cv::InputArray src, cv::OutputArray dst) {                         
  const auto& src_size = src.getMat().size;                                        
  const int src_c = src_size[0];                                                   
  const int src_h = src_size[1];                                                   
  const int src_w = src_size[2];                                                   

  auto c_hw = src.getMat().reshape(0, {src_c, src_h * src_w});                     

  cv::Mat hw_c;                                                                    
  cv::transpose(c_hw, hw_c);                                                       

  dst.assign(hw_c.reshape(src_c, {src_h, src_w}));                                 
}

The one problem with these are the unnecessary reallocation for dst. If cv::Mat had a constructor as fancy as cv::Mat::reshape() that accepted channels and depth rather than type we could easily reuse dst memory. Can someone make this reuse dst memory (with create)?

void hwc_to_chw(cv::InputArray src, cv::OutputArray dst) {
const int src_h = src.rows();
const int src_w = src.cols();
const int src_c = src.channels();

  cv::Mat hw_c = src.getMat().reshape(1, src_h * src_w);                        

  cv::transpose(hw_c, dst);                                                        
  dst.assign(dst.getMat().reshape(1, const std::array<int,3> dims = {src_c, src_h, src_w}));                      
}

// Max channels is currently 512
src_w};                         
  dst.create(3, &dims[0], CV_MAKETYPE(src.depth(), 1));                         
  cv::Mat dst_1d = dst.getMat().reshape(1, {src_c, src_h, src_w});              

  cv::transpose(hw_c, dst_1d);                                                  
}                                                                               

void chw_to_hwc(cv::InputArray src, cv::OutputArray dst) {                       
  const auto& src_size = src.getMat().size;                                      
  const int src_c = src_size[0];                                                 
  const int src_h = src_size[1];                                                 
  const int src_w = src_size[2];                                                 

  auto c_hw = src.getMat().reshape(0, {src_c, src_h * src_w});                   

  dst.create(src_h, src_w, CV_MAKETYPE(src.depth(), src_c));                    
  cv::Mat hw_c;                                                                    dst_1d = dst.getMat().reshape(src_c, {src_h, src_w});                 

  cv::transpose(c_hw, hw_c);                                                       

  dst.assign(hw_c.reshape(src_c, {src_h, src_w})); dst_1d);                                                  
}

The one problem with these are the unnecessary reallocation for dst. If cv::Mat had a constructor as fancy as cv::Mat::reshape() that accepted channels and depth rather than type we could easily reuse dst memory. Can someone make this reuse dst memory (with create)?

void hwc_to_chw(cv::InputArray src, cv::OutputArray dst) {
const int src_h = src.rows();
const int src_w = src.cols();
const int src_c = src.channels();

  cv::Mat hw_c = src.getMat().reshape(1, src_h * src_w);                        

  const std::array<int,3> dims = {src_c, src_h, src_w};                         
  dst.create(3, &dims[0], CV_MAKETYPE(src.depth(), 1));                         
  cv::Mat dst_1d = dst.getMat().reshape(1, {src_c, src_h, src_w});              

  cv::transpose(hw_c, dst_1d);                                                  
}                                                                               

void chw_to_hwc(cv::InputArray src, cv::OutputArray dst) {                      
  const auto& src_size = src.getMat().size;                                     
  const int src_c = src_size[0];                                                
  const int src_h = src_size[1];                                                
  const int src_w = src_size[2];                                                

  auto c_hw = src.getMat().reshape(0, {src_c, src_h * src_w});                  

  dst.create(src_h, src_w, CV_MAKETYPE(src.depth(), src_c));                    
  cv::Mat dst_1d = dst.getMat().reshape(src_c, {src_h, src_w});                 

  cv::transpose(c_hw, dst_1d);                                                  
}

void hwc_to_chw(cv::InputArray src, cv::OutputArray dst) {
{ const int src_h = src.rows();
src.rows(); const int src_w = src.cols();
src.cols(); const int src_c = src.channels(); src.channels();

  cv::Mat hw_c = src.getMat().reshape(1, src_h * src_w);                        
src_w);

  const std::array<int,3> dims = {src_c, src_h, src_w};                         
  dst.create(3, &dims[0], CV_MAKETYPE(src.depth(), 1));                         
  cv::Mat dst_1d = dst.getMat().reshape(1, {src_c, src_h, src_w});              

  cv::transpose(hw_c, dst_1d);                                                  
}                                                                               

void chw_to_hwc(cv::InputArray src, cv::OutputArray dst) {                      
  const auto& src_size = src.getMat().size;                                     
  const int src_c = src_size[0];                                                
  const int src_h = src_size[1];                                                
  const int src_w = src_size[2];                                                

  auto c_hw = src.getMat().reshape(0, {src_c, src_h * src_w});                  

  dst.create(src_h, src_w, CV_MAKETYPE(src.depth(), src_c));                    
  cv::Mat dst_1d = dst.getMat().reshape(src_c, {src_h, src_w});                 

  cv::transpose(c_hw, dst_1d);                                                  
}

The following has worked well for me, with no unnecessary data allocation:

void hwc_to_chw(cv::InputArray src, cv::OutputArray dst) {
   const int src_h = src.rows();
   const int src_w = src.cols();
   const int src_c = src.channels();

src.channels();

  cv::Mat hw_c = src.getMat().reshape(1, src_h * src_w);

  const std::array<int,3> dims = {src_c, src_h, src_w};                         
  dst.create(3, &dims[0], CV_MAKETYPE(src.depth(), 1));                         
  cv::Mat dst_1d = dst.getMat().reshape(1, {src_c, src_h, src_w});              

  cv::transpose(hw_c, dst_1d);                                                  
}                                                                               

void chw_to_hwc(cv::InputArray src, cv::OutputArray dst) {                      
  const auto& src_size = src.getMat().size;                                     
  const int src_c = src_size[0];                                                
  const int src_h = src_size[1];                                                
  const int src_w = src_size[2];                                                

  auto c_hw = src.getMat().reshape(0, {src_c, src_h * src_w});                  

  dst.create(src_h, src_w, CV_MAKETYPE(src.depth(), src_c));                    
  cv::Mat dst_1d = dst.getMat().reshape(src_c, {src_h, src_w});                 

  cv::transpose(c_hw, dst_1d);                                                  
}