diff --git a/code/C++/.clang-format b/code/C++/.clang-format index 4e695e3..d7f0a70 100644 --- a/code/C++/.clang-format +++ b/code/C++/.clang-format @@ -2,4 +2,8 @@ Language: Cpp BasedOnStyle: LLVM IndentWidth: 2 ColumnLimit: 132 -SortIncludes: CaseSensitive +SortIncludes: true +AlignAfterOpenBracket: DontAlign +AllowShortIfStatementsOnASingleLine: AllIfsAndElse +AllowShortLoopsOnASingleLine: true +# AllowShortNamespacesOnASingleLine: true diff --git a/code/C++/FIFO_w_OpenCV/.gitignore b/code/C++/FIFO_w_OpenCV/.gitignore new file mode 100644 index 0000000..53e31a2 --- /dev/null +++ b/code/C++/FIFO_w_OpenCV/.gitignore @@ -0,0 +1,3 @@ +# xmake +.xmake/ +build/ diff --git a/code/C++/FIFO_w_OpenCV/README.md b/code/C++/FIFO_w_OpenCV/README.md new file mode 100644 index 0000000..d7c6cd0 --- /dev/null +++ b/code/C++/FIFO_w_OpenCV/README.md @@ -0,0 +1,3 @@ +Пример отправки и получения `cv::Mat` через FIFO в неблокируемом потоке + +⚠️ Параметры изображения, такие как **размеры** и **каналы** не передаются. diff --git a/code/C++/FIFO_w_OpenCV/reader.cpp b/code/C++/FIFO_w_OpenCV/reader.cpp new file mode 100644 index 0000000..c75b28d --- /dev/null +++ b/code/C++/FIFO_w_OpenCV/reader.cpp @@ -0,0 +1,73 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define FIFO_NAME "cvMat" +#define MAX_BUF 150 * 150 * 4 + +using namespace cv; + +int main() { + unsigned int timeout_seconds = 2; + + while (true) { + int fd = open(FIFO_NAME, O_RDONLY | O_NONBLOCK); + if (fd < 0) { + perror("open"); + return EXIT_FAILURE; + } + + struct pollfd waiter = {.fd = fd, .events = POLLIN}; + + while (true) { + bool stop = false; + + int poll_result = poll(&waiter, 1, timeout_seconds * 1000); + switch (poll_result) { + case 0: + puts("No data from fifo"); + break; + + case 1: + if (waiter.revents & POLLIN) { + std::vector buff; + char tempBuff[256]; + ssize_t bytesRead; + + while ((bytesRead = read(fd, tempBuff, sizeof(tempBuff))) > 0) buff.insert(buff.end(), tempBuff, tempBuff + bytesRead); + printf("Received: %d\n", buff.size()); + + Mat img(cv::Size(810, 1080), CV_8UC3, buff.data()); + cv::imwrite("received.jpg", img); + } else if (waiter.revents & POLLERR) { + puts("Got a POLLERR"); + return EXIT_FAILURE; + } else if (waiter.revents & POLLHUP) { + stop = true; // Writer closed its end + break; + } + break; + + default: + perror("poll error"); + return EXIT_FAILURE; + } + + if (stop) break; + } + + if (close(fd) < 0) { + perror("close"); + return EXIT_FAILURE; + } + } + + return EXIT_SUCCESS; +} diff --git a/code/C++/FIFO_w_OpenCV/writer.cpp b/code/C++/FIFO_w_OpenCV/writer.cpp new file mode 100644 index 0000000..85a1ef5 --- /dev/null +++ b/code/C++/FIFO_w_OpenCV/writer.cpp @@ -0,0 +1,59 @@ +#include +#include + +#include +#include +#include + +#include + +#define FIFO_NAME "cvMat" + +// const std::vector imageFiles = {"bus.jpg", "cat_dog.jpg", "girl_faces.png"}; +const std::vector imageFiles = {"bus.jpg"}; + +cv::Mat getFrame(const std::string source); +std::string getRandomImage(std::vector images); + +int main(int argc, char const *argv[]) { + if (!mkfifo(FIFO_NAME, 0666)) { + std::perror("open"); + return EXIT_FAILURE; + } + + cv::Mat frame = getFrame(getRandomImage(imageFiles)); + cv::Mat flat = frame.reshape(1, frame.total() * frame.channels()); + std::vector buffer = frame.isContinuous() ? flat : flat.clone(); + + int fd = open(FIFO_NAME, O_WRONLY); + write(fd, buffer.data(), buffer.size()); + printf("Sended: %d\n", buffer.size()); + close(fd); + + cv::Mat my_mat = cv::Mat(frame.rows, frame.cols, frame.type(), buffer.data()); + cv::imwrite("sended.png", my_mat); + + return EXIT_SUCCESS; +} + +cv::Mat getFrame(const std::string source) { + cv::Mat image = cv::imread(source, cv::IMREAD_COLOR); + + if (image.empty()) { + std::perror("failed to load image"); + const cv::Mat emptyFrame(480, 640, CV_8UC3, cv::Scalar(44, 44, 44)); + return emptyFrame; + } else { + return image; + } +} + +std::string getRandomImage(std::vector images) { + std::random_device rd; + std::mt19937 gen(rd()); + std::uniform_int_distribution<> dis(0, images.size() - 1); + int randomIndex = dis(gen); + std::string randomString = images[randomIndex]; + + return randomString; +} diff --git a/code/C++/FIFO_w_OpenCV/xmake.lua b/code/C++/FIFO_w_OpenCV/xmake.lua new file mode 100644 index 0000000..918b5e3 --- /dev/null +++ b/code/C++/FIFO_w_OpenCV/xmake.lua @@ -0,0 +1,24 @@ +set_project("fifo_woth_opencv") +set_languages("c99", "cxx17") +add_rules("mode.debug", "mode.release") + +if is_mode("debug") then + set_symbols("debug") + set_optimize("none") +end + +add_includedirs( + "/usr/include/opencv4/" +) +add_linkdirs( +) + +target("reader") + set_kind("binary") + add_syslinks("opencv_highgui", "opencv_imgcodecs", "opencv_core") + add_files("reader.cpp") + +target("writer") + set_kind("binary") + add_syslinks("opencv_imgcodecs", "opencv_core") + add_files("writer.cpp")