mirror of
				https://github.com/RetroDECK/ES-DE.git
				synced 2025-04-10 19:15:13 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			351 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			351 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
| #
 | |
| #  File        : cvMat.h
 | |
| #                ( C++ header file - CImg plug-in )
 | |
| #
 | |
| #  Description : CImg plug-in providing the CImg->cvMat and cvMat->CImg
 | |
| #                conversions for generic image types
 | |
| #                ( IPL = Intel Performance Library )
 | |
| #                This file is a part of the CImg Library project.
 | |
| #                ( http://cimg.sourceforge.net )
 | |
| #
 | |
| #  Copyright   : Alberto Albiol
 | |
| #                alalbiol@iteam.upv.es
 | |
| #
 | |
| #  How to use  : In the main program include:
 | |
| #        #include "cv.h"
 | |
| #        #include "highgui.h"
 | |
| #        #define cimg_plugin1 "cvMat.h"
 | |
| #        #include "CImg.h"
 | |
| */
 | |
| #ifndef cimg_plugin_cvMat
 | |
| #define cimg_plugin_cvMat
 | |
| 
 | |
| // Conversion IPL -> CImg (constructor)
 | |
| CImg(const cv::Mat& src):_width(0),_height(0),_depth(0),_spectrum(0),_is_shared(false),_data(0) {
 | |
|   assign(src);
 | |
| }
 | |
| 
 | |
| // Conversion IPL -> CImg (in-place constructor)
 | |
| CImg<T>& assign(const cv::Mat & src) {
 | |
|   if (src.isContinuous()) {
 | |
|     switch (src.depth()) {
 | |
|         // case CV_1U: { // 1-bit int.
 | |
|         //    IplImage *src1 = cvCreateImage(cvGetSize(src),CV_8U,1);
 | |
|         //    cvConvert(src,src1);
 | |
|         //    CImg<ucharT>((unsigned char*)src1->imageData,src1->nChannels,src1.cols,src1.rows,1,true).
 | |
|         //      get_permute_axes("yzcx").move_to(*this);
 | |
|         //    cvReleaseImage(&src1);
 | |
|         //  } break;
 | |
|     case CV_8U: // 8-bit unsigned int.
 | |
|       if (src.channels()==1) {
 | |
|         CImg<ucharT>((unsigned char*)src.ptr(),src.cols,src.rows,true).move_to(*this);
 | |
|       } else {
 | |
|         std::vector<cv::Mat> channels;
 | |
|         cv::split(src,channels);
 | |
|         CImg<ucharT>
 | |
|           tmp(src.cols,src.rows,1,3),
 | |
|           R = tmp.get_shared_channel(2),
 | |
|           G = tmp.get_shared_channel(1),
 | |
|           B = tmp.get_shared_channel(0);
 | |
|         std::memcpy(R.data(),channels[0].ptr(),src.cols*src.rows*sizeof(uchar));
 | |
|         std::memcpy(G.data(),channels[1].ptr(),src.cols*src.rows*sizeof(uchar));
 | |
|         std::memcpy(B.data(),channels[2].ptr(),src.cols*src.rows*sizeof(uchar));
 | |
|         tmp.move_to(*this);
 | |
|       }
 | |
|       break;
 | |
|     case CV_8S: // 8-bit signed int.
 | |
|       if (src.channels()==1) {
 | |
|         CImg<charT>((char*)src.ptr(),src.cols,src.rows,true).move_to(*this);
 | |
|       } else {
 | |
|         std::vector<cv::Mat> channels;
 | |
|         cv::split(src,channels);
 | |
|         CImg<ucharT>
 | |
|           tmp(src.cols,src.rows,1,3),
 | |
|           R = tmp.get_shared_channel(2),
 | |
|           G = tmp.get_shared_channel(1),
 | |
|           B = tmp.get_shared_channel(0);
 | |
|         std::memcpy(R.data(),channels[0].ptr(),src.cols*src.rows*sizeof(char));
 | |
|         std::memcpy(G.data(),channels[1].ptr(),src.cols*src.rows*sizeof(char));
 | |
|         std::memcpy(B.data(),channels[2].ptr(),src.cols*src.rows*sizeof(char));
 | |
|         tmp.move_to(*this);
 | |
|       }
 | |
|       break;
 | |
|     case CV_16U: // 16-bit unsigned int.
 | |
|       if (src.channels()==1) {
 | |
|         CImg<ushortT>((unsigned short*)src.ptr(),src.cols,src.rows,true).move_to(*this);
 | |
|       } else {
 | |
|         std::vector<cv::Mat> channels;
 | |
|         cv::split(src,channels);
 | |
|         CImg<ushortT>
 | |
|           tmp(src.cols,src.rows,1,3),
 | |
|           R = tmp.get_shared_channel(2),
 | |
|           G = tmp.get_shared_channel(1),
 | |
|           B = tmp.get_shared_channel(0);
 | |
|         std::memcpy(R.data(),channels[0].ptr(),src.cols*src.rows*sizeof(unsigned short));
 | |
|         std::memcpy(G.data(),channels[1].ptr(),src.cols*src.rows*sizeof(unsigned short));
 | |
|         std::memcpy(B.data(),channels[2].ptr(),src.cols*src.rows*sizeof(unsigned short));
 | |
|         tmp.move_to(*this);
 | |
|       }
 | |
|       break;
 | |
|     case CV_16S: // 16-bit signed int.
 | |
|       if (src.channels()==1) {
 | |
|         CImg<shortT>((short*)src.ptr(),src.cols,src.rows,true).move_to(*this);
 | |
|       } else {
 | |
|         std::vector<cv::Mat> channels;
 | |
|         cv::split(src,channels);
 | |
|         CImg<shortT>
 | |
|           tmp(src.cols,src.rows,1,3),
 | |
|           R = tmp.get_shared_channel(2),
 | |
|           G = tmp.get_shared_channel(1),
 | |
|           B = tmp.get_shared_channel(0);
 | |
|         std::memcpy(R.data(),channels[0].ptr(),src.cols*src.rows*sizeof(short));
 | |
|         std::memcpy(G.data(),channels[1].ptr(),src.cols*src.rows*sizeof(short));
 | |
|         std::memcpy(B.data(),channels[2].ptr(),src.cols*src.rows*sizeof(short));
 | |
|         tmp.move_to(*this);
 | |
|       }
 | |
|       break;
 | |
|     case CV_32S: // 32-bit signed int.
 | |
|       if (src.channels()==1) {
 | |
|         CImg<intT>((int*)src.ptr(),src.cols,src.rows,true).move_to(*this);
 | |
|       } else {
 | |
|         std::vector<cv::Mat> channels;
 | |
|         cv::split(src,channels);
 | |
|         CImg<intT>
 | |
|           tmp(src.cols,src.rows,1,3),
 | |
|           R = tmp.get_shared_channel(2),
 | |
|           G = tmp.get_shared_channel(1),
 | |
|           B = tmp.get_shared_channel(0);
 | |
|         std::memcpy(R.data(),channels[0].ptr(),src.cols*src.rows*sizeof(int));
 | |
|         std::memcpy(G.data(),channels[1].ptr(),src.cols*src.rows*sizeof(int));
 | |
|         std::memcpy(B.data(),channels[2].ptr(),src.cols*src.rows*sizeof(int));
 | |
|         tmp.move_to(*this);
 | |
|       }
 | |
|       break;
 | |
|     case CV_32F: // 32-bit float.
 | |
|       if (src.channels()==1) {
 | |
|         CImg<floatT>((float*)src.ptr(),src.cols,src.rows,true).move_to(*this);
 | |
|       } else {
 | |
|         std::vector<cv::Mat> channels;
 | |
|         cv::split(src,channels);
 | |
|         CImg<floatT>
 | |
|           tmp(src.cols,src.rows,1,3),
 | |
|           R = tmp.get_shared_channel(2),
 | |
|           G = tmp.get_shared_channel(1),
 | |
|           B = tmp.get_shared_channel(0);
 | |
|         std::memcpy(R.data(),channels[0].ptr(),src.cols*src.rows*sizeof(float));
 | |
|         std::memcpy(G.data(),channels[1].ptr(),src.cols*src.rows*sizeof(float));
 | |
|         std::memcpy(B.data(),channels[2].ptr(),src.cols*src.rows*sizeof(float));
 | |
|         tmp.move_to(*this);
 | |
|       }
 | |
|       break;
 | |
|     case CV_64F: // 64-bit double.
 | |
|       if (src.channels()==1) {
 | |
|         CImg<doubleT>((double*)src.ptr(),src.cols,src.rows,true).move_to(*this);
 | |
|       } else {
 | |
|         std::vector<cv::Mat> channels;
 | |
|         cv::split(src,channels);
 | |
|         CImg<doubleT>
 | |
|           tmp(src.cols,src.rows,1,3),
 | |
|           R = tmp.get_shared_channel(2),
 | |
|           G = tmp.get_shared_channel(1),
 | |
|           B = tmp.get_shared_channel(0);
 | |
|         std::memcpy(R.data(),channels[0].ptr(),src.cols*src.rows*sizeof(double));
 | |
|         std::memcpy(G.data(),channels[1].ptr(),src.cols*src.rows*sizeof(double));
 | |
|         std::memcpy(B.data(),channels[2].ptr(),src.cols*src.rows*sizeof(double));
 | |
|         tmp.move_to(*this);
 | |
|       }
 | |
|       break;
 | |
|     default:
 | |
|       throw CImgInstanceException(_cimg_instance
 | |
|                                   "assign(const cv::Mat&) : Mat depth is invalid.",
 | |
|                                   cimg_instance);
 | |
|       break;
 | |
|     }
 | |
|   } else {
 | |
|     cv::Size size = src.size();
 | |
|     switch (src.depth()) {
 | |
|     case CV_8U: // 8-bit unsigned int.
 | |
|       if (src.channels()==1) {
 | |
|         CImg<ucharT> tmp(src.cols,src.rows);
 | |
|         for (int i = 0; i<size.height; ++i) {
 | |
|           const unsigned char* row_i = src.ptr<unsigned char>(i);
 | |
|           unsigned char *row_o = tmp.data(0,i);
 | |
|           std::memcpy(row_o,row_i,size.width*sizeof(unsigned char));
 | |
|         }
 | |
|         tmp.move_to(*this);
 | |
|       } else {
 | |
|         CImg<ucharT> tmp(src.cols,src.rows,1,src.channels());
 | |
|         std::vector<cv::Mat> channels;
 | |
|         cv::split(src,channels);
 | |
|         for (int c = 0; c<src.channels(); ++c) {
 | |
|           CImg<ucharT> plane = tmp.get_shared_channel(src.channels()-1-c);
 | |
|           for (int i = 0; i<size.height; ++i) {
 | |
|             const unsigned char* row_i = channels[c].ptr<unsigned char>(i);
 | |
|             unsigned char *row_o = plane.data(0,i);
 | |
|             std::memcpy(row_o,row_i,size.width*sizeof(unsigned char));
 | |
|           }
 | |
|         }
 | |
|         tmp.move_to(*this);
 | |
|       }
 | |
|       break;
 | |
|     case CV_8S: // 8-bit int.
 | |
|       if (src.channels()==1) {
 | |
|         CImg<charT> tmp(src.cols,src.rows);
 | |
|         for (int i = 0; i<size.height; ++i) {
 | |
|           const char* row_i = src.ptr<char>(i);
 | |
|           char* row_o = tmp.data(0,i);
 | |
|           std::memcpy(row_o,row_i,size.width*sizeof(charT));
 | |
|         }
 | |
|         tmp.move_to(*this);
 | |
|       } else {
 | |
|         CImg<charT> tmp(src.cols,src.rows,1,src.channels());
 | |
|         std::vector<cv::Mat> channels;
 | |
|         cv::split(src,channels);
 | |
|         for (int c = 0; c<src.channels(); ++c) {
 | |
|           CImg<charT> plane = tmp.get_shared_channel(src.channels()-1-c);
 | |
|           for (int i = 0; i<size.height; ++i) {
 | |
|             const char* row_i = channels[c].ptr<char>(i);
 | |
|             char *row_o = plane.data(0,i);
 | |
|             std::memcpy(row_o,row_i,size.width*sizeof(char));
 | |
|           }
 | |
|         }
 | |
|         tmp.move_to(*this);
 | |
|       }
 | |
|       break;
 | |
|     case CV_16S: // 16-bit int.
 | |
|       if (src.channels()==1) {
 | |
|         CImg<shortT> tmp(src.cols,src.rows);
 | |
|         for (int i = 0; i<size.height; ++i) {
 | |
|           const short* row_i = src.ptr<short>(i);
 | |
|           short *row_o = tmp.data(0,i);
 | |
|           std::memcpy(row_o,row_i,size.width*sizeof(short));
 | |
|         }
 | |
|         tmp.move_to(*this);
 | |
|       } else {
 | |
|         CImg<shortT> tmp(src.cols,src.rows,1,src.channels());
 | |
|         std::vector<cv::Mat> channels;
 | |
|         cv::split(src,channels);
 | |
|         for (int c = 0; c<src.channels(); ++c) {
 | |
|           CImg<shortT> plane = tmp.get_shared_channel(src.channels()-1-c);
 | |
|           for (int i = 0; i<size.height; ++i) {
 | |
|             const short* row_i = channels[c].ptr<short>(i);
 | |
|             short *row_o = plane.data(0,i);
 | |
|             std::memcpy(row_o,row_i,size.width*sizeof(short));
 | |
|           }
 | |
|         }
 | |
|         tmp.move_to(*this);
 | |
|       }
 | |
|       break;
 | |
|     case CV_32F: // 32-bit float.float
 | |
|       if (src.channels()==1) {
 | |
|         CImg<floatT> tmp(src.cols,src.rows);
 | |
|         for (int i = 0; i<size.height; ++i) {
 | |
|           const float* row_i = src.ptr<float>(i);
 | |
|           float *row_o = tmp.data(0,i);
 | |
|           std::memcpy(row_o,row_i,size.width*sizeof(float));
 | |
|         }
 | |
|         tmp.move_to(*this);
 | |
|       } else {
 | |
|         CImg<floatT> tmp(src.cols,src.rows,1,src.channels());
 | |
|         std::vector<cv::Mat> channels;
 | |
|         cv::split(src,channels);
 | |
|         for (int c = 0; c<src.channels(); ++c) {
 | |
|           CImg<floatT> plane = tmp.get_shared_channel(src.channels()-1-c);
 | |
|           for (int i = 0; i<size.height; ++i) {
 | |
|             const float* row_i = channels[c].ptr<float>(i);
 | |
|             float *row_o = plane.data(0,i);
 | |
|             std::memcpy(row_o,row_i,size.width*sizeof(float));
 | |
|           }
 | |
|         }
 | |
|         tmp.move_to(*this);
 | |
|       }
 | |
|       break;
 | |
|     case CV_64F: // 64-bit double.
 | |
|       if (src.channels()==1) {
 | |
|         CImg<doubleT> tmp(src.cols,src.rows);
 | |
|         for (int i = 0; i<size.height; ++i) {
 | |
|           const double* row_i = src.ptr<double>(i);
 | |
|           double *row_o = tmp.data(0,i);
 | |
|           std::memcpy(row_o,row_i,size.width*sizeof(double));
 | |
|         }
 | |
|         tmp.move_to(*this);
 | |
|       } else {
 | |
|         CImg<doubleT> tmp(src.cols,src.rows,1,src.channels());
 | |
|         std::vector<cv::Mat> channels;
 | |
|         cv::split(src,channels);
 | |
|         for (int c = 0; c<src.channels(); ++c) {
 | |
|           CImg<doubleT> plane = tmp.get_shared_channel(src.channels()-1-c);
 | |
|           for (int i = 0; i<size.height; ++i) {
 | |
|             const double* row_i = channels[c].ptr<double>(i);
 | |
|             double *row_o = plane.data(0,i);
 | |
|             std::memcpy(row_o,row_i,size.width*sizeof(double));
 | |
|           }
 | |
|         }
 | |
|         tmp.move_to(*this);
 | |
|       }
 | |
|       break;
 | |
|     default:
 | |
|       throw CImgInstanceException(_cimg_instance
 | |
|                                   "assign(const cv::Mat&) : Mat depth is invalid.",
 | |
|                                   cimg_instance);
 | |
|       break;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   //  if (!std::strcmp(src->channelSeq,"BGR")) mirror('v');
 | |
|   //  else if (!std::strcmp(src->channelSeq,"BGRA")) get_shared_channels(0,2).mirror('v');
 | |
|   return *this;
 | |
| }
 | |
| 
 | |
| // Conversion CImg -> MAT
 | |
| cv::Mat get_MAT(const unsigned int z=0) const {
 | |
|   if (is_empty())
 | |
|     throw CImgInstanceException(_cimg_instance
 | |
|                                 "get_MAT() : instance image is empty.",
 | |
|                                 cimg_instance);
 | |
|   if (z>=_depth)
 | |
|     throw CImgInstanceException(_cimg_instance
 | |
|                                 "get_MAT() : specified slice %u is out of image bounds.",
 | |
|                                 cimg_instance,z);
 | |
|   const CImg<T>
 | |
|     _slice = _depth>1?get_slice(z):CImg<T>(),
 | |
|     &slice = _depth>1?_slice:*this;
 | |
|   CImg<T> buf(slice,true);
 | |
|   int
 | |
|     cols = buf.width(),
 | |
|     rows = buf.height(),
 | |
|     nchannels = buf.spectrum(),
 | |
|     matType=-1;
 | |
| 
 | |
|   if (!cimg::strcasecmp(buf.pixel_type(),"unsigned char")) matType = CV_8UC1;
 | |
|   if (!cimg::strcasecmp(buf.pixel_type(),"uint8")) matType = CV_8UC1;
 | |
|   if (!cimg::strcasecmp(buf.pixel_type(),"char")) matType = CV_8SC1;
 | |
|   if (!cimg::strcasecmp(buf.pixel_type(),"int8")) matType = CV_8SC1;
 | |
|   if (!cimg::strcasecmp(buf.pixel_type(),"unsigned short")) matType = CV_16UC1;
 | |
|   if (!cimg::strcasecmp(buf.pixel_type(),"uint16")) matType = CV_16UC1;
 | |
|   if (!cimg::strcasecmp(buf.pixel_type(),"short")) matType = CV_16SC1;
 | |
|   if (!cimg::strcasecmp(buf.pixel_type(),"int16")) matType = CV_16SC1;
 | |
|   if (!cimg::strcasecmp(buf.pixel_type(),"int")) matType = CV_32SC1;
 | |
|   if (!cimg::strcasecmp(buf.pixel_type(),"int32")) matType = CV_32SC1;
 | |
|   if (!cimg::strcasecmp(buf.pixel_type(),"float")) matType = CV_32FC1;
 | |
|   if (!cimg::strcasecmp(buf.pixel_type(),"float32")) matType = CV_32FC1;
 | |
|   if (!cimg::strcasecmp(buf.pixel_type(),"double")) matType = CV_64FC1;
 | |
|   if (!cimg::strcasecmp(buf.pixel_type(),"float64")) matType = CV_64FC1;
 | |
|   if (matType<0)
 | |
|     throw CImgInstanceException(_cimg_instance
 | |
|                                 "get_MAT() : pixel type '%s' is not supported.",
 | |
|                                 cimg_instance,buf.pixel_type());
 | |
|   cv::Mat out;
 | |
|   std::vector<cv::Mat> channels(nchannels);
 | |
|   if (nchannels>1) {
 | |
|     for (int c = 0; c<nchannels; ++c) {
 | |
|       channels[c] = cv::Mat(rows,cols,matType,const_cast<T*>(buf.data()+rows*cols*(nchannels-1-c)));
 | |
|     } // for channels
 | |
|     cv::merge(channels,out);
 | |
|   } else out = cv::Mat(rows,cols,matType,const_cast<T*>(buf.data())).clone();
 | |
|   return out;
 | |
| }
 | |
| 
 | |
| #endif /* cimg_plugin_cvMat */
 | 
