From 4a68abd38e44c5c9362315c58ab97cbb683b1cae Mon Sep 17 00:00:00 2001 From: mmcwilliams Date: Wed, 24 Apr 2024 13:58:30 -0600 Subject: [PATCH] Update image to load image or blank, only loadBlank on startup. Error linking on macOS, testing Linux --- CMakeLists.txt | 1 + include/image.hpp | 5 +- src/image.cpp | 33 +++++++++- src/main.cpp | 149 +++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 183 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f12cec8..804af30 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,6 +12,7 @@ find_package(OpenGL REQUIRED) find_package(GLUT REQUIRED) find_package(OpenCV HINTS /usr/local/opt/opencv /usr/local/Cellar/opencv REQUIRED) + file(GLOB SOURCES "src/*.cpp") if(${TESTING_ON}) diff --git a/include/image.hpp b/include/image.hpp index 4443581..6327678 100644 --- a/include/image.hpp +++ b/include/image.hpp @@ -15,7 +15,9 @@ #include #include #include +#include +using namespace std; using namespace cv; class Image { @@ -25,8 +27,9 @@ class Image { Mat blank; public: Image(); - void setDimensions(uint16_t w, uint16_t h); + void setDimensions(uint16_t w, uint16_t h) { width = w; height = h; }; Mat getBlank(); + Mat loadImage(string& image_path, uint64_t& x, uint64_t& y, uint64_t& w, uint64_t& h); }; #endif \ No newline at end of file diff --git a/src/image.cpp b/src/image.cpp index 0f8bc70..0146074 100644 --- a/src/image.cpp +++ b/src/image.cpp @@ -1,5 +1,36 @@ #include "image.hpp" Image::Image () { - // + +} + +Mat Image::getBlank () { + return Mat::zeros(height, width, CV_8UC3); +} + +Mat Image::loadImage (string& image_path, uint64_t& x, uint64_t& y, uint64_t& w, uint64_t& h) { + string located_path = samples::findFile(image_path); + Mat loaded = imread(located_path, IMREAD_COLOR); + Mat image = getBlank(); + + if (image.empty()) { + cerr << "Image " << image << " empty" << endl; + } else { + cout << "loaded " << image_path << endl; + cout << " dim " << loaded.cols << "x" << loaded.rows << endl; + + //resize(loaded, resized, Size(1280, 1080)); + cout << " image " << image.cols << "x" << image.rows << endl; + //cout << "resized " << resized.cols << "x" << resized.rows << endl; + //resized.copyTo(image(Rect(0, 0, resized.cols, resized.rows))); + loaded.copyTo(image(Rect(x, y, loaded.cols, loaded.rows))); + flip(image, image, 0); + +#if (CV_VERSION_MAJOR >= 4) + cvtColor(image, image, cv::COLOR_BGR2RGB); +#else + cvtColor(image, image, CV_BGR2RGB); +#endif + } + return image; } \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index fbedd2e..beb90b4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,6 +1,15 @@ #include "image.hpp" #include "state.hpp" +#ifdef __APPLE__ + #include + #include + #include +#else + #include + #include +#endif + #include #include #include @@ -13,12 +22,100 @@ using namespace std; -uint16_t PORT = 8081; -uint16_t BUFFER_SIZE = 2048; +const uint16_t PORT = 8081; +const uint16_t BUFFER_SIZE = 2048; + +GLuint imageTexture; +GLuint blankTexture; + +GLint screenWidth = 0; +GLint screenHeight = 0; Image img; State state; + + +void actionDisplay () { + +} + +void actionLoad () { + string imagePath = state.getImage(); + vector position = state.getPosition(); + Mat image = img.loadImage(imagePath, position[0], position[1], position[2], position[3]); + glGenTextures(2, &imageTexture); + glBindTexture(GL_TEXTURE_2D, imageTexture); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + + glTexImage2D(GL_TEXTURE_2D, // Type of texture + 0, // Pyramid level (for mip-mapping) - 0 is the top level + GL_RGB, // Internal colour format to convert to + image.cols, // Image width i.e. 640 for Kinect in standard mode + image.rows, // Image height i.e. 480 for Kinect in standard mode + 0, // Border width in pixels (can either be 1 or 0) + GL_RGB, // Input image format (i.e. GL_RGB, GL_RGBA, GL_BGR etc.) + GL_UNSIGNED_BYTE, // Image data type + image.ptr()); // The actual image data itself +} + +void actionStop () { + +} + +void loadBlank () { + Mat blank = img.getBlank(); + glGenTextures(1, &blankTexture); + glBindTexture(GL_TEXTURE_2D, blankTexture); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + + glTexImage2D(GL_TEXTURE_2D, // Type of texture + 0, // Pyramid level (for mip-mapping) - 0 is the top level + GL_RGB, // Internal colour format to convert to + blank.cols, // Image width i.e. 640 for Kinect in standard mode + blank.rows, // Image height i.e. 480 for Kinect in standard mode + 0, // Border width in pixels (can either be 1 or 0) + GL_RGB, // Input image format (i.e. GL_RGB, GL_RGBA, GL_BGR etc.) + GL_UNSIGNED_BYTE, // Image data type + blank.ptr()); // The actual image data itself +} + +void display () { + glClear(GL_COLOR_BUFFER_BIT); + glEnable(GL_TEXTURE_2D); + glViewport(0, 0, screenWidth, screenHeight); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); + glBindTexture(GL_TEXTURE_2D, imageTexture); + + glBegin(GL_QUADS); // front face + glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 0.0f); //bottom right + glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 0.0f); //top right + glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 0.0f); //top left + glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 0.0f); //bottom left + glEnd(); + glDisable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, 0); + glutSwapBuffers(); + + //glFlush(); +} + +/** + * State Message Variables + **/ + bool receivedMessage = false; bool sendMessage = false; string incomingMessage; @@ -30,6 +127,10 @@ condition_variable receivedCondVar; mutex sendMutex; condition_variable sendCondVar; +/** + * + **/ + void processMessage () { if (receivedMessage) { cout << "RECEIVED" << endl; @@ -37,7 +138,13 @@ void processMessage () { receivedMessage = false; while (state.isActive()) { - // + if (state.getAction() == LOAD) { + actionLoad(); + } else if (state.getAction() == DISPLAY) { + actionDisplay(); + } else if (state.getAction() == STOP) { + actionStop(); + } } if (state.isError()) { @@ -112,7 +219,43 @@ void runTCPServer (int serverSocket) { } } +uint8_t handleArgs (int argc, char** argv) { + if (argc > 1) { + screenWidth = atoi(argv[1]); + cout << "Set width: " << screenWidth << endl; + } else { + cerr << "Please provide screen width as first argument" << endl; + return 1; + } + if (argc > 2) { + screenHeight = atoi(argv[2]); + cout << "Set height: " << screenHeight << endl; + } else { + cerr << "Please provide screen height as second argument" << endl; + return 2; + } + return 0; +} + int main (int argc, char** argv) { + uint8_t argsRet = handleArgs(argc, argv); + + if (argsRet > 0) { + return argsRet; + } + + img.setDimensions( (uint16_t) screenWidth, (uint16_t) screenHeight); + + loadBlank(); + + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_SINGLE); + glutCreateWindow("opengl_opencv_example"); + glutSetCursor(GLUT_CURSOR_NONE); + glutFullScreen(); + glutDisplayFunc(display); + glutMainLoop(); + int serverSocket = socket(AF_INET, SOCK_STREAM, 0); if (serverSocket < 0) { cerr << "Error creating socket" << endl;