OSDN Git Service

add JPG and TIFF Support via OpenCV for Image::load and Image::save
authorhskwk <hosokawa.kenchi@gmail.com>
Thu, 26 Feb 2015 12:50:32 +0000 (21:50 +0900)
committerhskwk <hosokawa.kenchi@gmail.com>
Thu, 26 Feb 2015 12:50:32 +0000 (21:50 +0900)
psychlops/core/graphic/psychlops_g_image.cpp
psychlops/core/graphic/psychlops_g_image.h
psychlops/extension/FileFormat/OpenCV/psychlops_g_OPENCV_bridge.cpp [new file with mode: 0644]
psychlops/extension/FileFormat/OpenCV/psychlops_g_OPENCV_bridge.h [new file with mode: 0644]
win32gl/dev/psychlopswin32.cbp
win32gl/test/Psychlops_win32cblibtest.cbp
win32gl/test/opencvtest.cpp
win32gl/test/shader/ShaderLoader.cpp [new file with mode: 0644]

index ff09c4c..d003429 100644 (file)
@@ -27,9 +27,7 @@
 #include "psychlops_g_image.h"
 
 #include "../../extension/FileFormat/PNG/psychlops_g_PNG_bridge.h"
-#if 0
-#include "../../extension/FileFormat/JPEG/psychlops_g_JPEG_bridge.h"
-#endif
+#include "../../extension/FileFormat/OpenCV/psychlops_g_OPENCV_bridge.h"
 
 
 namespace Psychlops {
@@ -631,17 +629,20 @@ void Image::pix_ub_bits_mono_(int ix, int iy, double lum) {
                }
                std::string::size_type extention_index = filename.find_last_of('.');
                if(extention_index==std::string::npos) throw Exception(typeid(*this), "File Type Error", "Specified image type is not supported.*..");
-               std::string file_extension = filename.substr(extention_index+1);
-               if(file_extension=="png") {
+               std::string file_extension = filename.substr(extention_index+1);\r
+               IMAGE_FORMATS::FILE_EXT ext = IMAGE_FORMATS::getImageFileFormatFromExt(file_extension);\r
+               if(ext==IMAGE_FORMATS::PNG) {
                        loader = new IMAGE_FORMATS::PNG_BRIDGE;
                        loader->load(File::decodePath(filename).c_str(), this);
                        delete loader;
-#if 0
-               } else if(file_extension=="jpg") {
-                       loader = new IMAGE_FORMATS::JPEG_BRIDGE;
+               } else if(ext==IMAGE_FORMATS::JPG) {
+                       loader = new IMAGE_FORMATS::OPENCV_BRIDGE;
+                       loader->load(File::decodePath(filename).c_str(), this);
+                       delete loader;
+               } else if(ext==IMAGE_FORMATS::TIFF) {
+                       loader = new IMAGE_FORMATS::OPENCV_BRIDGE;
                        loader->load(File::decodePath(filename).c_str(), this);
                        delete loader;
-#endif
                } else {
                        throw Exception(typeid(*this), "File Type Error", "Specified image type is not supported.");
                }
@@ -689,11 +690,20 @@ void Image::pix_ub_bits_mono_(int ix, int iy, double lum) {
 
                std::string::size_type extention_index = filename.find_last_of('.');
                if(extention_index==std::string::npos) throw Exception(typeid(*this), "File Type Error", "Specified image type is not supported.");
-               std::string file_extension = filename.substr(extention_index+1);
-               if(file_extension=="png") {
+               std::string file_extension = filename.substr(extention_index+1);\r
+               IMAGE_FORMATS::FILE_EXT ext = IMAGE_FORMATS::getImageFileFormatFromExt(file_extension);
+               if(ext==IMAGE_FORMATS::PNG) {
                        loader = new IMAGE_FORMATS::PNG_BRIDGE;
                        loader->save(File::decodePath(filename).c_str(), tmp);
                        delete loader;
+               } else if(ext==IMAGE_FORMATS::JPG) {
+                       loader = new IMAGE_FORMATS::OPENCV_BRIDGE;
+                       loader->save(File::decodePath(filename).c_str(), tmp);
+                       delete loader;
+               } else if(ext==IMAGE_FORMATS::TIFF) {
+                       loader = new IMAGE_FORMATS::OPENCV_BRIDGE;
+                       loader->save(File::decodePath(filename).c_str(), tmp);
+                       delete loader;
                } else {
                        throw Exception(typeid(*this), "File Type Error", "Specified image type is not supported.");
                }
@@ -889,9 +899,31 @@ void Image::pix_ub_bits_mono_(int ix, int iy, double lum) {
                        return *this;
                }
 
+namespace IMAGE_FORMATS {\r
+\r
+       FILE_EXT getImageFileFormatFromExt(const std::string &s) {\r
+               std::string ext = s;\r
+               std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower);\r
+               if(ext=="png") {\r
+                       return PNG;\r
+               } else if(ext=="jpg") {\r
+                       return JPG;\r
+               } else if(ext=="jpeg") {\r
+                       return JPG;\r
+               } else if(ext=="jp2") {\r
+                       return JP2;\r
+               } else if(ext=="tiff") {\r
+                       return TIFF;\r
+               } else if(ext=="cvmat") {\r
+                       return CVMAT_TXT;\r
+               } else if(ext=="mat") {\r
+                       return MATLAB_MAT;\r
+               } else {\r
+                       return UNKNOWN;\r
+               }\r
+       }\r
+\r
 
-
-namespace IMAGE_FORMATS {
        IMAGE_FORMAT::~IMAGE_FORMAT() {
        }
        void IMAGE_FORMAT::readTargetMemoryAlignment(Image *target) {
index 6289e84..eca5402 100644 (file)
@@ -24,7 +24,10 @@ namespace cv{ class Mat; }
 
 namespace Psychlops {
 
-namespace IMAGE_FORMATS {
+namespace IMAGE_FORMATS {\r
+       enum FILE_EXT { UNKNOWN, PNG, JPG, JP2, TIFF, CVMAT_TXT, MATLAB_MAT };\r
+       static FILE_EXT getImageFileFormatFromExt(const std::string &s);\r
+
        class IMAGE_FORMAT {
                protected:
                float * target_bitmap_f_;
diff --git a/psychlops/extension/FileFormat/OpenCV/psychlops_g_OPENCV_bridge.cpp b/psychlops/extension/FileFormat/OpenCV/psychlops_g_OPENCV_bridge.cpp
new file mode 100644 (file)
index 0000000..215d321
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ *  psychlops_g_PNG_bridge.cpp
+ *  Psychlops Standard Library (Universal)
+ *
+ *  Last Modified 2006/08/22 by Kenchi HOSOKAWA
+ *  (C) 2006- Kenchi HOSOKAWA, Kazushi MARUYA and Takao SATO
+ */
+
+#include <stdio.h>
+#include <stdlib.h>\r
+#include <opencv2/highgui/highgui.hpp>
+
+#include "../../../core/ApplicationInterfaces/psychlops_code_exception.h"
+#include "../../../core/graphic/psychlops_g_image.h"
+#include "psychlops_g_OPENCV_bridge.h"
+
+
+namespace Psychlops {
+namespace IMAGE_FORMATS {
+
+
+       OPENCV_BRIDGE::OPENCV_BRIDGE() {
+       }
+       OPENCV_BRIDGE::~OPENCV_BRIDGE() {
+       }
+
+
+       void OPENCV_BRIDGE::load(const char *file_name, Image * target) {\r
+               std::string file(file_name);\r
+               cv::Mat img = cv::imread(file, -1);\r
+               target->from(img);
+       }
+       void OPENCV_BRIDGE::save(const char *file_name, Image * target) {\r
+               std::string file(file_name);\r
+               cv::Mat img;\r
+               target->to(img);\r
+               cv::imwrite(file, img);
+       }
+
+
+}
+}
diff --git a/psychlops/extension/FileFormat/OpenCV/psychlops_g_OPENCV_bridge.h b/psychlops/extension/FileFormat/OpenCV/psychlops_g_OPENCV_bridge.h
new file mode 100644 (file)
index 0000000..e8f4b43
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ *  psychlops_g_PNG_bridge.h
+ *  Psychlops Standard Library (Universal)
+ *
+ *  Last Modified 2006/08/22 by Kenchi HOSOKAWA
+ *  (C) 2006- Kenchi HOSOKAWA, Kazushi MARUYA and Takao SATO
+ */
+
+#ifndef HEADER_PSYCHLOPS_IMAGE_FORMATS_OPENCV
+#define HEADER_PSYCHLOPS_IMAGE_FORMATS_OPENCV
+
+#ifndef __cplusplus
+#define __cplusplus
+#endif
+
+#include "../../../core/graphic/psychlops_g_image.h"
+
+
+namespace Psychlops {
+namespace IMAGE_FORMATS {
+
+
+       class OPENCV_BRIDGE : public IMAGE_FORMAT {
+               private:
+
+               public:
+               OPENCV_BRIDGE();
+               virtual ~OPENCV_BRIDGE();
+               virtual void load(const char *file_name, Image * target);
+               virtual void save(const char *file_name, Image * target);
+
+               private:
+       };
+
+
+}
+}
+
+#endif
index 4661b47..285fb6a 100644 (file)
                <Unit filename="../../psychlops/extension/FileFormat/JPEG/jpeglib.h" />
                <Unit filename="../../psychlops/extension/FileFormat/JPEG/psychlops_g_JPEG_bridge.cpp" />
                <Unit filename="../../psychlops/extension/FileFormat/JPEG/psychlops_g_JPEG_bridge.h" />
+               <Unit filename="../../psychlops/extension/FileFormat/OpenCV/psychlops_g_OPENCV_bridge.cpp" />
+               <Unit filename="../../psychlops/extension/FileFormat/OpenCV/psychlops_g_OPENCV_bridge.h" />
                <Unit filename="../../psychlops/extension/FileFormat/PNG/png.h" />
                <Unit filename="../../psychlops/extension/FileFormat/PNG/pngconf.h" />
                <Unit filename="../../psychlops/extension/FileFormat/PNG/psychlops_g_PNG_bridge.cpp" />
index 79f0dce..b0cb6ef 100644 (file)
                        <Option compile="0" />
                        <Option link="0" />
                </Unit>
+               <Unit filename="shader/ShaderLoader.cpp">
+                       <Option compile="0" />
+                       <Option link="0" />
+               </Unit>
                <Unit filename="shader/ShaderPlaidsBench.cpp">
                        <Option compile="0" />
                        <Option link="0" />
index a9637cb..53b6245 100644 (file)
@@ -120,15 +120,13 @@ void psychlops_main() {
                        motion_vector_arrow.draw();\r
                }\r
 */\r
-\r
-               movie.captureOnce();\r
+               //movie.captureOnce();\r
                cnvs.flip();\r
                CANVAS_FRAMENUM++;\r
        }\r
        ///- 3 Drawing /////////////////////////////////////////////////////////////////\r
 \r
-\r
-       movie.save("test.avi", 15);\r
+       //movie.save("test.avi", 15);\r
        //cv1\r
     //cvReleaseCapture( &videoCapture );\r
 }\r
diff --git a/win32gl/test/shader/ShaderLoader.cpp b/win32gl/test/shader/ShaderLoader.cpp
new file mode 100644 (file)
index 0000000..2ed152a
--- /dev/null
@@ -0,0 +1,295 @@
+#include <psychlops.h>
+using namespace Psychlops;     // Initially developed with Psychlops Win32 1.4.6 / 20100325
+
+std::string error_message;
+
+void loadGLSL(std::stringstream &buf, const std::string path)
+{
+       char one;
+       std::ifstream is;
+       is.open(path.c_str(), std::ifstream::in);
+       if(is.fail()) {
+               Widgets::Dialog::alert(L"File was not found, or failed to read for some reasons.");
+               return;
+       }
+       while(is.good()) {
+               is.get(one);
+               buf << one;
+       }
+}
+void logError()
+{
+       std::ofstream os;
+       os.open("GLSLTesterErrorLog.txt");
+       if(os.fail()) {
+               Widgets::Dialog::alert(L"File was not found, or failed to read for some reasons.");
+               return;
+       }
+       os << error_message;
+}
+
+const char *default_field_glsl =
+                       "in float red;"
+                       "void main(void){ "
+                       "pix(red,0.0,0.0,1.0); }";
+
+Figures::ShaderField field;
+char *source_field = (char*)default_field_glsl;
+void cacheShaderField(const std::string path)
+{
+       std::stringstream buf;
+       loadGLSL(buf, path);
+
+       try{
+               field.setFunction(buf.str());
+               field.cache(*Display::the_canvas);
+               error_message.clear();
+       } catch (Exception e) {
+               error_message = e.getErrorString();
+               logError();
+       } catch (Exception *e) {
+               error_message = e->getErrorString();
+               logError();
+       }
+}
+
+const char *default_image_glsl =
+       "in float dr, dg, db, da;"
+       "void main(void) {"
+       "vec4 d = vec4(dr, dg, db, da);"
+       "pix(getPix()+d);}";
+Figures::ShaderImage image;
+char *source_image = (char*)default_image_glsl;
+Image shadered_image, dummy_image;
+void cacheShaderImage(const std::string path)
+{
+       std::stringstream buf;
+       loadGLSL(buf, path);
+       try{
+               image.setFunction(buf.str().c_str());
+               image.cache(*Display::the_canvas);
+               error_message.clear();
+       } catch (Exception e) {
+               error_message = e.getErrorString();
+               logError();
+       } catch (Exception *e) {
+               error_message = e->getErrorString();
+               logError();
+       }
+}
+
+
+
+
+class RangedSlider : public Widgets::WidgetRect
+{
+       public:
+       static Interval itvl[6];
+       static void initialize() {
+               0<=itvl[0]<=1;
+               -1<=itvl[1]<=1;
+               0<=itvl[2]<=100;
+               -100<=itvl[3]<=100;
+               0<=itvl[4]<=2*PI;
+               -2*PI<=itvl[5]<=2*PI;
+       }
+       bool active;
+       Widgets::Slider slide;
+       Widgets::SelectBox box;
+       RangedSlider& set(std::string lab, double hei) {
+               const Color ic(0,0,1,0.7), oc(.5,.5,.5,.5);
+               slide.set(lab, itvl[0]);
+               slide.area.fill = oc;
+               slide.internal.fill = ic;
+               box.append(L"[0, 1]");
+               box.append(L"[-1, 1]");
+               box.append(L"[0, 100]");
+               box.append(L"[-100, 100]");
+               box.append(L"[0, 2PI]");
+               box.append(L"[-2PI, 2PI]");
+               area.set(slide.getWidth()/3, hei);
+               return *this;
+       }
+       RangedSlider& draw(Drawable &target = *Drawable::prime)
+       {
+               if(active) {
+                       if(box.pushed()) {
+                               double ratio = slide.getRatio();
+                               slide.setInterval(itvl[box.getSelected()]);
+                               slide.setByRatio(ratio);
+                       }
+                       slide.area.set(getWidth()-90, getHeight()).alignLeft(getLeft()).alignTop(getTop());
+                       slide.draw(target);
+                       box.area.set(88, getHeight()).alignRight(getRight()).alignTop(getTop());
+                       box.draw(target);
+               }
+               return *this;
+       }
+};
+Interval RangedSlider::itvl[6];
+const int SHADER_ARG_MAX = 16;
+
+
+void ShaderTestTool() {
+
+       Canvas cnvs(800, 600, Canvas::window);
+
+       int view = 0;
+       const double DEFAULT_IMAGE_SIZE = 200.0;
+       shadered_image.set(DEFAULT_IMAGE_SIZE, DEFAULT_IMAGE_SIZE);
+       for(int x=0; x<DEFAULT_IMAGE_SIZE; x++) for(int y=0; y<DEFAULT_IMAGE_SIZE; y++) shadered_image.pix(x,y,Color(x/DEFAULT_IMAGE_SIZE, y/DEFAULT_IMAGE_SIZE, 0));
+       shadered_image.cache();
+
+
+       Widgets::StackPanel buttons;
+       Widgets::Button loader[3];
+       loader[0].set(L"Load GLSL/field", 18);
+       buttons.append(&loader[0]);
+       loader[1].set(L"Load GLSL/image", 18);
+       buttons.append(&loader[1]);
+       loader[2].set(L"Load PNG image", 18);
+       buttons.append(&loader[2]);
+       buttons.setWidth(150);
+       buttons.alignLeft(cnvs.getWidth() - 152).alignTop(cnvs.getHeight() - 18*4);
+       Drawable::billboard.append(buttons);
+
+
+       Psychlops::Rectangle area(300,300);
+       area.centering();
+
+       double Z[SHADER_ARG_MAX];
+       for(int i=0; i<SHADER_ARG_MAX; i++) Z[i] = 0.0;
+
+       RangedSlider sliders[SHADER_ARG_MAX];
+       RangedSlider::initialize();
+       Widgets::StackPanel panel;
+       std::stringstream wss;
+       for(int i=0; i<SHADER_ARG_MAX; i++) {
+               wss.str("");
+               wss << "var[" << i << "] ";
+               sliders[i].set("0", 18);
+               sliders[i].slide.label.setString(wss.str().c_str());
+               sliders[i].slide.link(Z[i], RangedSlider::itvl[0], 1);
+               panel.append(&sliders[i]);
+       }
+       panel.setWidth(200).shift(10,10);
+
+
+       std::string path[3];
+       Letters pathname[3];
+
+       std::string tmps;
+       field.setFunction(default_field_glsl);
+       field.cache(*Display::the_canvas);
+       for(int i=0; i<field.orig_args.size(); i++) {
+               tmps.assign(field.orig_args[i]).append(" ");
+               sliders[i].slide.label.setString(tmps.c_str());
+               sliders[i].active = true;
+       }
+       for(int i=field.orig_args.size(); i<SHADER_ARG_MAX; i++) {
+               sliders[i].active = false;
+       }
+//     image.setFunction(default_image_glsl);
+//     image.cache(*Display::the_canvas);
+
+       int error;
+
+       while(!Input::get(Keyboard::esc)) {
+               Display::clear();
+
+               if(loader[0].pushed()) {
+                       try {
+                               path[0] = Widgets::Dialog::getOpenFileName();
+                               cacheShaderField(path[0]);
+                               path[0].append("   OK ");
+                               pathname[0].fill = Color::yellow;
+                               error = 1;
+                               view = 0;
+                               for(int i=0; i<field.orig_args.size(); i++) {
+                                       tmps.assign(field.orig_args[i]).append(" ");
+                                       sliders[i].slide.label.setString(tmps.c_str());
+                                       sliders[i].active = true;
+                               }
+                               for(int i=field.orig_args.size(); i<SHADER_ARG_MAX; i++) {
+                                       sliders[i].active = false;
+                               }
+                       } catch(Exception e) {
+                               path[0] = e.to_s();
+                               pathname[0].fill = Color::red;
+                               error = -1;
+                       }
+                       pathname[0].setString(path[0].c_str());
+               }
+               if(loader[1].pushed()) {
+                       try {
+                               path[1] = Widgets::Dialog::getOpenFileName();
+                               cacheShaderImage(path[1]);
+                               path[1].append("   OK ");
+                               pathname[1].fill = Color::yellow;
+                               error = 1;
+                               view = 1;
+                               for(int i=0; i<image.orig_args.size(); i++) {
+                                       tmps.assign(image.orig_args[i]).append(" ");
+                                       sliders[i].slide.label.setString(tmps.c_str());
+                                       sliders[i].active = true;
+                               }
+                               for(int i=image.orig_args.size(); i<SHADER_ARG_MAX; i++) {
+                                       sliders[i].active = false;
+                               }
+                       } catch(Exception e) {
+                               path[1] = e.to_s();
+                               pathname[1].fill = Color::red;
+                               error = -1;
+                       }
+                       pathname[1].setString(path[1].c_str());
+               }
+               if(loader[2].pushed()) {
+                       try {
+                               path[2] = Widgets::Dialog::getOpenFileName();
+                               dummy_image.load(path[2]);
+                               shadered_image.load(path[2]);
+                               shadered_image.cache();
+                               path[2].append("   OK ");
+                               pathname[2].fill = Color::yellow;
+                               error = 1;
+                       } catch(Exception e) {
+                               path[2] = e.to_s();
+                               pathname[2].fill = Color::red;
+                               error = -1;
+                       }
+                       pathname[2].setString(path[2].c_str());
+               }
+
+               switch(view) {
+               case 1:
+                       shadered_image.centering();
+                       image.draw(shadered_image, Z, 3, *Display::the_canvas);
+                       break;
+               case 0:
+               default:
+                       field.draw(area, Z, 3, *Display::the_canvas);
+                       break;
+               }
+               panel.draw();
+               buttons.draw();
+               for(int i=0; i<3; i++) {
+                       pathname[i].font.size = 15;
+                       pathname[i].locate(loader[i].area.getLeft() - 20, loader[i].area.getBottom()-2).align = Letters::TEXT_ALIGN_RIGHT;
+                       pathname[i].draw();
+               }
+               if(!error_message.empty()) cnvs.msg(error_message, 200,20,Color::yellow);
+               cnvs.flip();
+               if(AppState::shouldBeClose) return;
+       }
+
+}
+
+
+void psychlops_main() {
+       Procedure p;
+       p.setDesign(Procedure::DEMO);
+       p.setProcedure(ShaderTestTool);
+       p.run();
+
+}
+