Изображение показывается поврежденным на локальном хосте - PullRequest
1 голос
/ 11 октября 2019

Я ужасно плохо знаком с c ++ и программированием в целом. Я просто пытаюсь прочитать изображение с помощью opencv и отобразить его на веб-сервере с помощью boost asio. Это начальный шаг, прежде чем я сделаю это для всех кадров из видео. Ниже приведен мой код -

#include <iostream>
#include <string>
#include <boost/asio.hpp>
#include <thread>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>

using boost::asio::ip::tcp;
using namespace std;
using namespace cv;

int main(){
    try{
        boost::asio::io_service io_service;
        tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 1112));

        for (;;){
            tcp::socket socket(io_service);
            acceptor.accept(socket);
            boost::system::error_code ignored_error;

            cv::Mat frame = cv::imread("x.jpg");
            vector<uchar> buff;
            vector<int> param = vector<int>(2);
            param[0]=cv::IMWRITE_JPEG_QUALITY;
            param[1]=95;
            imencode(".jpg",frame,buff,param);

            const char mess[] = "axaxaxaxasaaaaaaaaaaxax";

            std::string content(buff.begin(), buff.end());

            boost::asio::write(socket, boost::asio::buffer(content), boost::asio::transfer_all(), ignored_error);
            // boost::asio::write(socket, boost::asio::buffer(mess), boost::asio::transfer_all(), ignored_error);
        }
    }
    catch(std::exception& e)
    {
        std::cerr << e.what() << std::endl;
    }
    return 0;
}

Теперь отправка сообщения работает нормально, но когда я пытаюсь отправить изображение с помощью содержимого или баффа, оно отображается как бред. Я чувствую, что это потому, что я не отправляю информацию о картинке до ее отправки. Но я не могу понять, как это сделать. Или, может быть, я совершенно не прав. Любая помощь / совет будет оценен. Ура!

1 Ответ

1 голос
/ 11 октября 2019

Я немного упростил код:

#include <iostream>
#include <string>
#include <boost/asio.hpp>
#include <opencv2/opencv.hpp>

using boost::asio::ip::tcp;

int main(){
    try{
        boost::asio::io_service io_service;
        tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 1112));

        for (;;){
            tcp::socket socket(io_service);
            acceptor.accept(socket);

            cv::Mat frame = cv::imread("x.jpg");
            std::vector<uchar> buff;
            imencode(".jpg", frame, buff, std::vector<int> { cv::IMWRITE_JPEG_QUALITY, 95 });

            boost::system::error_code err;
            auto bytes_transferred = boost::asio::write(socket, boost::asio::buffer(buff), boost::asio::transfer_all(), err);

            std::cout << "Written: " << bytes_transferred << " (" << err.message() << ")\n";
        }
    }
    catch(std::exception& e)
    {
        std::cerr << e.what() << std::endl;
    }
}

(в частности, не используйте using namespace без необходимости, не копируя в std :: string без необходимости, ибез необходимости игнорировать код ошибки)

Скомпилировал его с помощью

g++ test.cpp -L/usr/local/lib -pedantic -Wall -Wextra -pthread -lope^Cv_{core,imgproc,imgcodecs} -lboost_{system,thread} -o test.exe

Скопировал spepe jpeg как x.jpg, запустив его в терминале:

./test.exe

Затем с помощью netcat для чтения результата:

netcat localhost 1112 > verify.jpg

Процесс сервера будет печатать одно и то же сообщение каждый раз:

Written: 6130 (Success)

(6130 байт получается95% перекодированного размера тестового изображения, которое я выбрал). Полученное изображение (verify.jpg) выглядит хорошо в моей программе просмотра изображений.

Заключение

Я думаю, что код, вероятно, в порядке (но проверьте с улучшениями выше), и вы, возможно, тестировалирезультат неправильный.

...