gRPC C C++を利用してopencvのmatタイプのピクチャーを伝送します-第2の高効率の方法---私はレンガを運ぶ大学生です

6169 ワード

前言
前回は別の記事でgRPC c++を利用して画像を転送する方法について書きました.詳細は以下を参照してください.
https://blog.csdn.net/liyangbinbin/article/details/100538412
しかし、効率は高くありません.サーバーでもクライアントでもM*N(画像サイズはMxN)回のサイクルが必要なので、小さな画像ではまあまあですが、大きな画像では効率があまりよくありません.後でメモリブロックをコピーする方法を見ました.1行ずつコピーすることで、サイクル数を減らすことができます.BUT.美人はすべて知っていることができて、指针のこの游びはすぐに不法访问で、间违いを指して、今回行って、次回またどんな鬼がだめだと知らないで、たとえ行っても、更にmatのピクチャーを逆解する时ピクチャーはすべて変形して、私はとても気性がなくて、大声で街を飞び出して、それからcapcopのブロガーの1篇の文章を见て、详しくは:
https://blog.csdn.net/tt_ren/article/details/53227900
Opencvには復号符号化の関数imdecode/imencodeがあったのですが、本当に使いやすくて、こんなに複雑な操作メモリを使わずにポインタを管理することができました.ダイレクトコード
クライアントコード
#pragma comment(lib,"ws2_32.lib")
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include "uppic.grpc.pb.h"
#include 
#include 
#include 
#include "opencv.hpp"
#include 
#include 
#include 
using grpc::Status;
using grpc::Channel;
using grpc::ClientContext;
using grpc::ClientWriter;
using namespace namespace_uploadpic;
using grpc::ClientContext;
#define GRPC_DEFAULT_MAX_RECV_MESSAGE_LENGTH(INT_MAX)
class uppicIml
{
public:
	//    ,      ,       
	uppicIml(std::shared_ptrchannl) :stu_(upload_pic_servicer::NewStub(channl)) {}
	void uppp()
	{
		//    ChunkOneLine* vector,         
		std::vectorchunkonelie;
		//      
		cv::Mat img = cv::imread("C:/Users/Administrator/Desktop/888.bmp");
		 ChunkOneLine *sedchunk = new ChunkOneLine();
		 Chunk *chunk=new Chunk();
		 //      
		 std::chrono::system_clock::time_point start_time = std::chrono::system_clock::now();
		 //       data  ,   uchar   vector
		 std::vector data_encode;
		 //    
		 cv::imencode(".jpg", img, data_encode);
		 std::cout << "size: " << sizeof(data_encode) << std::endl;
		 //  string  
		 std::string str_encode(data_encode.begin(), data_encode.end());
		 //    string  buff  ,
		 chunk->set_allocated_buff(&str_encode);
		 sedchunk->set_allocated_databuf(chunk);
		ClientContext context;
		//               
		Reply reply;
		//    API(      )   
		std::unique_ptr> writer=stu_->Upload(&context, &reply);
		//   (  )
		if (!writer->Write(*sedchunk))
		{
			//break;
			std::cout << "error!
"; } // writer->WritesDone(); // grpc::Status status = writer->Finish(); // std::chrono::system_clock::time_point end_time = std::chrono::system_clock::now(); //duration_cast , ,milliseconds , //(end_time - start_time) milliseconds, auto sec = std::chrono::duration_cast<:chrono::milliseconds>(end_time - start_time); if (status.ok()) { std::cout << "
"; std::cout << " :" <stu_; }; int main() { // //CreateChannel , , uppicIml upppp(grpc::CreateChannel("127.0.0.1:50051", grpc::InsecureChannelCredentials())); // upppp.uppp(); system("pause"); return 0; }

サービス側コード
#include
#include 
#include 
#include 
#include 
#include 
#include 
#include "uppic.grpc.pb.h"
#include 
#include 
#include "opencv.hpp"
#include 
#include 
//    
using grpc::Server;
using grpc::ServerBuilder;
using grpc::ServerContext;
using grpc::ServerReader;
using grpc::Status;
using grpc::Channel;
using namespace namespace_uploadpic;
using grpc::ClientContext;
#define GRPC_DEFAULT_MAX_RECV_MESSAGE_LENGTH(INT_MAX)
void disyly(cv::Mat mat)
{
	cv::imshow("aa", mat);
	cv::waitKey(1);
}
class upPicserver final :public namespace_uploadpic::upload_pic_servicer::Service
{
public:
	//  Upload    rpc     
	Status Upload(ServerContext *context, ServerReader *reader, Reply *reply);
};
Status upPicserver::Upload(ServerContext *context, ServerReader *reader, Reply *reply)
{
	//      
	std::chrono::system_clock::time_point start_time =std::chrono::system_clock::now();
	//       
	ChunkOneLine oneLie;
	
	// 
	if (!reader->Read(&oneLie))
	{
		std::cout <data(str_decon.begin(),str_decon.end());
	//    
	mat = cv::imdecode(data, 1);
	//enum {
	//	CV_LOAD_IMAGE_UNCHANGED = -1, /* 8 bit, color or not */
	//	CV_LOAD_IMAGE_GRAYSCALE = 0,  /* 8 bit, gray */
	//	CV_LOAD_IMAGE_COLOR = 1,      /* ?, color */
	//	CV_LOAD_IMAGE_ANYDEPTH = 2,   /* any depth, ? */
	//	CV_LOAD_IMAGE_ANYCOLOR = 4    /* ?, any color */
	//};
 
	//        
	std::chrono::system_clock::time_point end_time = std::chrono::system_clock::now();
	//duration_cast     ,         ,milliseconds        ,
	//(end_time - start_time)     milliseconds,     
	auto sec = std::chrono::duration_cast<:chrono::milliseconds>(end_time - start_time);
	
	
	//            
	reply->set_length(sec.count());
	cv::imshow("bb", mat);
	//cv::moveWindow("bb", 100, 100);
	cv::waitKey(1);
	return grpc::Status::OK;
}
int main()
{
	//          
	upPicserver service;
	//     ,   IP  ,    0,0,0,0 127.0.0.1  
	//        IP 
	std::string add_ip("0.0.0.0:50051");
	//       
	ServerBuilder builder;
	//  ,           ssl  
	builder.SetMaxReceiveMessageSize(INT_MAX);
	//builder.SetMaxSendMessageSize(INT_MAX);
	builder.AddListeningPort(add_ip, grpc::InsecureServerCredentials());
	//              
	builder.RegisterService(&service);
 
	//  
	std::unique_ptrserver(builder.BuildAndStart());
	
	std::cout <Wait();
 
 
	return 0;
}

結果
ノートパソコンのカメラを画像入力として使用し、速度は40~60ミリ秒以内で、基本的にはネットカメラになることができますが、効果は悪くありません.