diff options
| author | Tim Redfern <tim@herge.(none)> | 2013-07-10 16:38:13 +0100 |
|---|---|---|
| committer | Tim Redfern <tim@herge.(none)> | 2013-07-10 16:38:13 +0100 |
| commit | edd05e4ad726c5aec6807a30dc9ff7de8f97b28b (patch) | |
| tree | afa0086a501f278b53f961b5991cad86be0072d5 | |
| parent | 0606ec24cbc1301b50f9f4bb2eae030d0658315f (diff) | |
cv::Mat use for images
| -rw-r--r-- | opencv/cvimage.h | 56 | ||||
| -rw-r--r-- | opencv/hello-opencv.cpp | 1 | ||||
| -rw-r--r-- | opencv/hello-opencv.d | 16 | ||||
| -rw-r--r-- | rotord/Makefile | 2 | ||||
| -rw-r--r-- | rotord/cvimage.h | 265 | ||||
| -rwxr-xr-x | rotord/rotor.h | 7 |
6 files changed, 330 insertions, 17 deletions
diff --git a/opencv/cvimage.h b/opencv/cvimage.h index b96f704..7588673 100644 --- a/opencv/cvimage.h +++ b/opencv/cvimage.h @@ -1,8 +1,21 @@ #include <math.h> +#include <cv.h> using namespace std; //converting to use a cv image... +//cv::Mat supports most of what we want here +//need to think +//http://answers.opencv.org/question/8202/using-external-image-data-in-a-cvmat/ + +//all access to the image is presently through a pointer to the data +//cv::Mat supports this + +//how will copying work? +//Rotor::Image will contain a cv::Mat object which may own its data or inherit it +//cv::Mat should take care of reference counting + +//can cv::Mat namespace Rotor { class pixeltables{ @@ -74,6 +87,13 @@ namespace Rotor { ownsRGBdata=ownsAdata=ownsZdata=false; } bool setup(int _w,int _h){ //set up with internal data + rgb.create(_w,_h,CV_8UC3); + RGBdata=rgb.data; //can move to use the bare pointer eventually + ownsRGBdata=false; //will not be necessary + w=_w; + h=_h; + return true; + /* if (w!=_w||h!=_h||!ownsRGBdata||!ownsAdata||!ownsZdata){ free(); w=_w; @@ -85,8 +105,18 @@ namespace Rotor { return true; } else return false; + */ } - bool setup_fromRGB(int _w,int _h,uint8_t *pRGBdata){ //possibility of just resetting pointer? + bool setup_fromRGB(int _w,int _h,uint8_t *pRGBdata){ + //here the data belongs to libavcodec or other + //could move to using cv::Mat there also and just passing cv:Mat over + rgb=cv::Mat(_w,_h,CV_8UC3,pRGBdata); + RGBdata=rgb.data; //can move to use the bare pointer eventually + ownsRGBdata=false; //will not be necessary + w=_w; + h=_h; + return true; + /* if (w!=_w||h!=_h||ownsRGBdata||!ownsAdata||!ownsZdata){ free(); w=_w; @@ -99,14 +129,32 @@ namespace Rotor { return true; } return false; + */ + } + bool setup_fromMat(cv::Mat& othermat){ + //here the mat belongs to another Image object + rgb=cv::Mat(othermat); + RGBdata=rgb.data; //can move to use the bare pointer eventually + ownsRGBdata=false; //will not be necessary + w=rgb.rows; + h=rgb.cols; + return true; } Image* clone(){ - Image *t=new Image(w,h); + Image *t=new Image(); + t->rgb=rgb.clone(); + t->w=w; + t->h=h; + t->RGBdata=t->rgb.data; //can move to use the bare pointer eventually + t->ownsRGBdata=false; //will not be necessary + /* for (int i=0;i<w*h*3;i++) { t->RGBdata[i]=RGBdata[i]; } + */ return t; } + //believe these still work, don't know if these optimisations are better than opencvs.. Image & operator+=(const Image &other) { if (other.w!=w||other.h!=h) { cerr<<"Rotor: cannot add images with different sizes! (wanted "<<w<<"x"<<h<<", got "<<other.w<<"x"<<other.h<<")"<<endl; @@ -126,8 +174,6 @@ namespace Rotor { else { for (int i=0;i<w*h*3;i++){ //calculate with tables - uint8_t p1=RGBdata[i]; - uint8_t p2=other.RGBdata[i]; RGBdata[i]=pixels.multiply[RGBdata[i]][other.RGBdata[i]]; } } @@ -213,5 +259,7 @@ namespace Rotor { uint16_t *Zdata; int h,w; bool ownsRGBdata,ownsAdata,ownsZdata; //better done through auto_ptr? + + cv::Mat rgb; }; }
\ No newline at end of file diff --git a/opencv/hello-opencv.cpp b/opencv/hello-opencv.cpp index ed8de6b..8f0c566 100644 --- a/opencv/hello-opencv.cpp +++ b/opencv/hello-opencv.cpp @@ -16,7 +16,6 @@ #include <stdlib.h> #include <stdio.h> #include <math.h> -#include <cv.h> #include <highgui.h> #include "cvimage.h" diff --git a/opencv/hello-opencv.d b/opencv/hello-opencv.d index eebafe9..c7b95b9 100644 --- a/opencv/hello-opencv.d +++ b/opencv/hello-opencv.d @@ -33,10 +33,10 @@ /usr/include/i386-linux-gnu/bits/nan.h \ /usr/include/i386-linux-gnu/bits/mathdef.h \ /usr/include/i386-linux-gnu/bits/mathcalls.h \ - /usr/include/i386-linux-gnu/bits/mathinline.h /usr/include/opencv/cv.h \ - /usr/include/opencv2/core/core_c.h /usr/include/opencv2/core/types_c.h \ - /usr/include/assert.h /usr/include/string.h \ - /usr/include/i386-linux-gnu/bits/string3.h \ + /usr/include/i386-linux-gnu/bits/mathinline.h \ + /usr/include/opencv/highgui.h /usr/include/opencv2/core/core_c.h \ + /usr/include/opencv2/core/types_c.h /usr/include/assert.h \ + /usr/include/string.h /usr/include/i386-linux-gnu/bits/string3.h \ /usr/lib/gcc/i686-linux-gnu/4.7/include/float.h \ /usr/lib/gcc/i686-linux-gnu/4.7/include/stdint.h /usr/include/stdint.h \ /usr/include/i386-linux-gnu/bits/wchar.h \ @@ -141,7 +141,9 @@ /usr/include/c++/4.7/bits/stl_multimap.h \ /usr/include/opencv2/core/operations.hpp \ /usr/include/opencv2/core/mat.hpp \ - /usr/include/opencv2/imgproc/imgproc_c.h \ + /usr/include/opencv2/highgui/highgui_c.h \ + /usr/include/opencv2/highgui/highgui.hpp cvimage.h \ + /usr/include/opencv/cv.h /usr/include/opencv2/imgproc/imgproc_c.h \ /usr/include/opencv2/imgproc/types_c.h \ /usr/include/opencv2/imgproc/imgproc.hpp \ /usr/include/opencv2/video/tracking.hpp \ @@ -191,6 +193,4 @@ /usr/include/opencv2/legacy/compat.hpp \ /usr/include/opencv2/core/internal.hpp \ /usr/include/i386-linux-gnu/sys/mman.h \ - /usr/include/i386-linux-gnu/bits/mman.h /usr/include/opencv/highgui.h \ - /usr/include/opencv2/highgui/highgui_c.h \ - /usr/include/opencv2/highgui/highgui.hpp cvimage.h + /usr/include/i386-linux-gnu/bits/mman.h diff --git a/rotord/Makefile b/rotord/Makefile index 05c2243..86ae740 100644 --- a/rotord/Makefile +++ b/rotord/Makefile @@ -9,7 +9,7 @@ MY_CFLAGS = -fpermissive -std=c++11 -I /usr/include/opencv # -I ../ffmpeg # The linker options.libgstaasinklibgstaasink.so -MY_LIBS = -lPocoNet -lPocoXML -lPocoUtil -lPocoFoundation -lvamp-hostsdk -lsndfile -L /usr/local/lib -lswscale -lavcodec -lavformat -lavfilter -lavdevice -lavutil -lstdc++ -lm +MY_LIBS = -lopencv_core -lopencv_video -lopencv_highgui -lPocoNet -lPocoXML -lPocoUtil -lPocoFoundation -lvamp-hostsdk -lsndfile -L /usr/local/lib -lswscale -lavcodec -lavformat -lavfilter -lavdevice -lavutil -lstdc++ -lm #MY_LIBS = -lPocoNet -lPocoXML -lPocoUtil -lPocoFoundation -lvamp-hostsdk -lsndfile -L /usr/local/lib -lswscale -lavcodec -lavformat -lavfilter -lavdevice -lavutil $(shell pkg-config gstreamer-0.10 gstreamer-video-0.10 gstreamer-base-0.10 --libs) # -lgstreamer-0.10 -lgstreamer-video-0.10 -lgstreamer-base-0.10 -lglib-2.0 -lgstapp-0.10 #MY_LIBS = ../libavcodec/ffmpeg/libavcodec/libavcodec.a ../libavcodec/ffmpeg/libavutil/libavutil.a ../libavcodec/ffmpeg/libavformat/libavformat.a ../libavcodec/ffmpeg/libavfilter/libavfilter.a ../libavcodec/ffmpeg/libavdevice/libavdevice.a -lPocoNet -lPocoXML -lPocoUtil -lPocoFoundation -lvamp-hostsdk diff --git a/rotord/cvimage.h b/rotord/cvimage.h new file mode 100644 index 0000000..7588673 --- /dev/null +++ b/rotord/cvimage.h @@ -0,0 +1,265 @@ +#include <math.h> +#include <cv.h> + +using namespace std; + +//converting to use a cv image... +//cv::Mat supports most of what we want here +//need to think +//http://answers.opencv.org/question/8202/using-external-image-data-in-a-cvmat/ + +//all access to the image is presently through a pointer to the data +//cv::Mat supports this + +//how will copying work? +//Rotor::Image will contain a cv::Mat object which may own its data or inherit it +//cv::Mat should take care of reference counting + +//can cv::Mat + +namespace Rotor { + class pixeltables{ + //handy pixel arithmetic lookup tables as nested arrays + //so - pixels.add[0x78][0x66]; will give the precalculated result of adding with saturation + // pixels.mono_weights[0][0x100]; will give the red component to convert to mono + public: + pixeltables(){ + add=new uint8_t*[256]; + multiply=new uint8_t*[256]; + for (int i=0;i<256;i++){ + add[i]=new uint8_t[256]; + multiply[i]=new uint8_t[256]; + for (int j=0;j<256;j++){ + add[i][j]=(uint8_t)min(i+j,0xFF); + multiply[i][j]=(uint8_t)((((float)i)/255.0f)*(((float)j)/255.0f)*255.0f); + } + } + mono_weights=new uint8_t*[3]; + float weights[3]={0.2989, 0.5870, 0.1140}; + for (int i=0;i<3;i++) { + mono_weights[i]=new uint8_t[256]; + for (int j=0;j<256;j++){ + mono_weights[i][j]=(uint8_t)(((float)j)*weights[i]); + } + } + } + virtual ~pixeltables(){ + for (int i=0;i<256;i++){ + delete[] add[i]; + delete[] multiply[i]; + } + delete[] add; + delete[] multiply; + for (int i=0;i<3;i++) { + delete[] mono_weights[i]; + } + delete[] mono_weights; + } + uint8_t **add; + uint8_t **multiply; + uint8_t **mono_weights; + }; + static pixeltables pixels; + class Image{ + public: + Image(){ + zero(); + }; + Image(int _w,int _h){ + zero(); + setup(_w,_h); + }; + ~Image() { + free(); + }; + void free(){ + if (RGBdata&&ownsRGBdata) delete[] RGBdata; + if (Adata&&ownsAdata) delete[] Adata; + if (Zdata&&ownsZdata) delete[] Zdata; + zero(); + } + void zero(){ + RGBdata=nullptr; + Adata=nullptr; + Zdata=nullptr; + w=0; + h=0; + ownsRGBdata=ownsAdata=ownsZdata=false; + } + bool setup(int _w,int _h){ //set up with internal data + rgb.create(_w,_h,CV_8UC3); + RGBdata=rgb.data; //can move to use the bare pointer eventually + ownsRGBdata=false; //will not be necessary + w=_w; + h=_h; + return true; + /* + if (w!=_w||h!=_h||!ownsRGBdata||!ownsAdata||!ownsZdata){ + free(); + w=_w; + h=_h; + RGBdata=new uint8_t[w*h*3]; + Adata=new uint8_t[w*h]; + Zdata=new uint16_t[w*h]; + ownsRGBdata=ownsAdata=ownsZdata=true; + return true; + } + else return false; + */ + } + bool setup_fromRGB(int _w,int _h,uint8_t *pRGBdata){ + //here the data belongs to libavcodec or other + //could move to using cv::Mat there also and just passing cv:Mat over + rgb=cv::Mat(_w,_h,CV_8UC3,pRGBdata); + RGBdata=rgb.data; //can move to use the bare pointer eventually + ownsRGBdata=false; //will not be necessary + w=_w; + h=_h; + return true; + /* + if (w!=_w||h!=_h||ownsRGBdata||!ownsAdata||!ownsZdata){ + free(); + w=_w; + h=_h; + RGBdata=pRGBdata; + Adata=new uint8_t[w*h]; + Zdata=new uint16_t[w*h]; + ownsRGBdata=false; + ownsAdata=ownsZdata=true; + return true; + } + return false; + */ + } + bool setup_fromMat(cv::Mat& othermat){ + //here the mat belongs to another Image object + rgb=cv::Mat(othermat); + RGBdata=rgb.data; //can move to use the bare pointer eventually + ownsRGBdata=false; //will not be necessary + w=rgb.rows; + h=rgb.cols; + return true; + } + Image* clone(){ + Image *t=new Image(); + t->rgb=rgb.clone(); + t->w=w; + t->h=h; + t->RGBdata=t->rgb.data; //can move to use the bare pointer eventually + t->ownsRGBdata=false; //will not be necessary + /* + for (int i=0;i<w*h*3;i++) { + t->RGBdata[i]=RGBdata[i]; + } + */ + return t; + } + //believe these still work, don't know if these optimisations are better than opencvs.. + Image & operator+=(const Image &other) { + if (other.w!=w||other.h!=h) { + cerr<<"Rotor: cannot add images with different sizes! (wanted "<<w<<"x"<<h<<", got "<<other.w<<"x"<<other.h<<")"<<endl; + } + else { + for (int i=0;i<w*h*3;i++){ + //calculate with tables + RGBdata[i]=pixels.add[RGBdata[i]][other.RGBdata[i]]; + } + } + return *this; + } + Image & operator*=(const Image &other) { + if (other.w!=w||other.h!=h) { + cerr<<"Rotor: cannot multiply images with different sizes! (wanted "<<w<<"x"<<h<<", got "<<other.w<<"x"<<other.h<<")"<<endl; + } + else { + for (int i=0;i<w*h*3;i++){ + //calculate with tables + RGBdata[i]=pixels.multiply[RGBdata[i]][other.RGBdata[i]]; + } + } + return *this; + } + Image & add_wrap(const Image &other) { + if (other.w!=w||other.h!=h) { + cerr<<"Rotor: cannot add images with different sizes! (wanted "<<w<<"x"<<h<<", got "<<other.w<<"x"<<other.h<<")"<<endl; + } + else { + for (int i=0;i<w*h*3;i++){ + //creates rainbow overload + RGBdata[i]=(unsigned char)(((int)other.RGBdata[i]+(int)RGBdata[i])); + } + } + return *this; + } + //scalar operations allocate a new image. + //maybe this could not be the case if the data is owned by this image? + //need to look into auto_ptr + Image & operator*=(const float &amount) { + uint8_t *LUT=new uint8_t[256]; + for (int i=0;i<256;i++) { + LUT[i]=(uint8_t)min(0xFF,max(0,(int)(i*amount))); + } + for (int i=0;i<w*h*3;i++){ + //calculate with table + RGBdata[i]=LUT[RGBdata[i]]; + } + delete[] LUT; + return *this; + } + Image * operator*(const float &amount) { + Image *other=new Image(w,h); + uint8_t *LUT=new uint8_t[256]; + for (int i=0;i<256;i++) { + LUT[i]=(uint8_t)min(0xFF,max(0,(int)(i*amount))); + } + for (int i=0;i<w*h*3;i++){ + other->RGBdata[i]=LUT[RGBdata[i]]; + } + delete[] LUT; + return other; + } + Image * operator+(const float &amount) { + Image *other=new Image(w,h); + uint8_t *LUT=new uint8_t[256]; + for (int i=0;i<256;i++) { + LUT[i]=(uint8_t)min(0xFF,max(0,(int)(i+(amount*255.0f)))); + } + for (int i=0;i<w*h*3;i++){ + other->RGBdata[i]=LUT[RGBdata[i]]; + } + delete[] LUT; + return other; + } + Image * operator-(const float &amount) { + Image *other=new Image(w,h); + uint8_t *LUT=new uint8_t[256]; + for (int i=0;i<256;i++) { + LUT[i]=(uint8_t)min(0xFF,max(0,(int)(i-(amount*255.0f)))); + } + for (int i=0;i<w*h*3;i++){ + other->RGBdata[i]=LUT[RGBdata[i]]; + } + delete[] LUT; + return other; + } + Image * operator/(const float &amount) { + Image *other=new Image(w,h); + uint8_t *LUT=new uint8_t[256]; + for (int i=0;i<256;i++) { + LUT[i]=(uint8_t)min(0xFF,max(0,(int)(i/amount))); + } + for (int i=0;i<w*h*3;i++){ + other->RGBdata[i]=LUT[RGBdata[i]]; + } + delete[] LUT; + return other; + } + uint8_t *RGBdata; + uint8_t *Adata; + uint16_t *Zdata; + int h,w; + bool ownsRGBdata,ownsAdata,ownsZdata; //better done through auto_ptr? + + cv::Mat rgb; + }; +}
\ No newline at end of file diff --git a/rotord/rotor.h b/rotord/rotor.h index 8e6e9b7..3d260e4 100755 --- a/rotord/rotor.h +++ b/rotord/rotor.h @@ -1,3 +1,4 @@ + /* nodes can have many inputs but only 1 output @@ -68,7 +69,7 @@ extern "C" { #include "xmlIO.h" #include "utils.h" //fequal #include "libavwrapper.h" -#include "image.h" +#include "cvimage.h" namespace Rotor { #define IDLE 0 @@ -565,8 +566,8 @@ namespace Rotor { image->RGBdata[(i*frame.w+j)*3]=(uint8_t)((int)((i+(frame.time*25.0f)*hs))%255); image->RGBdata[((i*frame.w+j)*3)+1]=(uint8_t)((int)((j+(frame.time*100.0f)*hs))%255); image->RGBdata[((i*frame.w+j)*3)+2]=(uint8_t)(0); - image->Adata[i*frame.w+j]=(uint8_t)255; - image->Zdata[i*frame.w+j]=(uint16_t)512; //1.0 in fixed point 8.8 bits + //image->Adata[i*frame.w+j]=(uint8_t)255; + //image->Zdata[i*frame.w+j]=(uint16_t)512; //1.0 in fixed point 8.8 bits } } return image; |
