linux opencv傳遞網(wǎng)絡攝像頭數(shù)據(jù)--Apple的學習筆記

一,遇到問題

1.段溢出砂代?

根本原因:vector申請后沒有釋放蹋订,導致段溢出。
調試方法:通過gdb調試core文件找到原因刻伊。
解決方案:添加clear及swap函數(shù)來釋放內存露戒。

2.client沒有顯示出圖片?

根本原因:都沒有收到一張完整的圖片就開始imshow導致捶箱。
調試方法:添加imwrite把數(shù)據(jù)保存來看效果智什。
解決方法:添加waitkey延時

3.client通過imwrite只能保存幾張相對完好的圖片?imshow顯示為黑色

根本原因:imwrite的數(shù)據(jù)不完整丁屎。
調試方法:1. 通過添加握手來分別傳輸長度+jpg數(shù)據(jù)荠锭。
2. 通過打印log來看size的值是否和預期傳輸一致。
解決方法:client接收大數(shù)據(jù)時候晨川,需要while多次來接收证九,否則一個size的只總是小于預期接收,它只要收到數(shù)據(jù)共虑,則不會阻塞愧怜,代碼會繼續(xù)往下走。

二妈拌,直接學到的經(jīng)驗

  1. c++ vector的使用拥坛,申請控件,清空內存供炎,與char轉換渴逻。
  2. imwrite和imdecode等函數(shù)的應用。(jpg等壓縮參數(shù)值)
  3. send和revc函數(shù)的使用及返回值的作用音诫。
  4. socket通信的基本流程惨奕。
  5. socket大數(shù)據(jù)傳輸處理方式。socket的阻塞體驗竭钝。
  6. core的gdb調試方法梨撞。
  7. cmake添加g++編譯的方法。
  8. 各個c++函數(shù)對應的頭文件香罐。
  9. int轉字符串的方法卧波。
  10. stringstream的數(shù)據(jù)流使用。
    11.通過編譯報錯來直接找到原因庇茫。

三港粱,直接了解的相關經(jīng)驗

  1. socket粘包處理方法。
  2. 顯示幀率與sleep時間的計算。
  3. jpg圖像的格式查坪。

四寸宏,客戶端和服務器交互說明

服務器向讀取攝像頭數(shù)據(jù)向客戶端先發(fā)長度,獲取客戶端ACK后再像客戶端發(fā)送壓縮為JPG的數(shù)據(jù)偿曙。


交互圖.png

五氮凝,linux 客戶端代碼

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include <arpa/inet.h>
#include<vector>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/videoio.hpp>
#include <unistd.h>
#include <iostream>

using namespace std;
using namespace cv;

/* tansfer int to string */
string int2string(int value)
{
    stringstream ss;
    ss<<value;
    return ss.str();
}

int main(int argc, char** argv)
{
    int    sockfd, n;
    char    recvline[4096], sendline[4096];
    struct sockaddr_in    servaddr;
    
    #if 0
    if( argc != 2){
    printf("usage: ./client <ipaddress>\n");
    exit(0);
    }
    #endif

    if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
    printf("create socket error: %s(errno: %d)\n", strerror(errno),errno);
    exit(0);
    }

    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(8080);
    if( inet_pton(AF_INET, "192.168.7.4", &servaddr.sin_addr) <= 0){
    printf("inet_pton error for %s\n",argv[1]);
    exit(0);
    }

    if( connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0){
    printf("connect error: %s(errno: %d)\n",strerror(errno),errno);
    exit(0);
    }

    #define BUF_SIZE 65535
    char buffer[ BUF_SIZE ];
    vector<char> vec;
    Mat img_decode; 
    string filename="";   
    int size = 0;
    int mylen = 0;
    int j= 0;
    char cokstart[ 1 ]={0x33};
    memset( buffer, 0, 4 );
    while(1)
    {
        size = recv(sockfd,buffer,4,0);
    
        mylen = ((buffer[2]<<8)&(0xFF00))|((buffer[3])&(0xFF));
        if (mylen>0){
            /*received length then send ack signal cokstart.*/  
            send(sockfd, cokstart, 1, 0);      
        }
        /* receive one frame of jpg data */
        while(mylen) 
        {
            size=recv(sockfd,buffer,mylen,0);
            //printf("size is %d\n",size);
            //printf("mylen is %x\n",mylen);
            /* put char values to vector */
            for(int i = 0 ; i < mylen ; i ++)  
            {  
                vec.push_back(buffer[i]);
            }
            mylen = mylen-size;  
        }
        
        /* decode jpg data */
        img_decode = imdecode(vec, CV_LOAD_IMAGE_COLOR); 
        /* release vector then ready to receive next frame */
        vec.clear();
        //cout << "vector capacity:"<<vec.capacity()<<endl;
        vector<char>(vec).swap(vec);
        //cout << "vector capacity afterswap:"<<vec.capacity()<<endl;
        
        /* display the jpg in windows */
        namedWindow("pic",WINDOW_AUTOSIZE);
        if(!img_decode.empty()){
            imshow("pic",img_decode);     
        }
        
        /* reflash display window in every 33ms */
        cvWaitKey(33);
        
        /* save to file -- this function is optional */
        j++;
        filename = "pic"+int2string(j)+".jpg";
        imwrite(filename,img_decode);   
        
        /* send ack signal cok to tell that I'm ready to handler next frame */
        char cok[ 1 ]={0x55};
        send(sockfd, cok, 1, 0);
    }
}

六,服務器代碼

#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include <opencv2/core.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
#include <vector>

using namespace std; 
using namespace cv;

/* tansfer int to string */
string int2string(int value)
{
    stringstream ss;
    ss<<value;
    return ss.str();
}

int main(int argc, char** argv)
{
    int    listenfd, connfd;
    struct sockaddr_in     servaddr;
    char    buff[4096];
    int     n;
    int sendbytes;

    if( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1 )
    {
        printf("create socket error: %s(errno: %d)\n",strerror(errno),errno);
        exit(0);
    }
    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(8080);

    int opt = 1;
    /* set port reuse */
    if(setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,(const void *)&opt,sizeof(opt)))
    {
        perror("setsockopt");
        return -1;
    }

    if( bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1){
        printf("bind socket error: %s(errno: %d)\n",strerror(errno),errno);
        exit(0);
    }

    if( listen(listenfd, 10) == -1){
        printf("listen socket error: %s(errno: %d)\n",strerror(errno),errno);
        exit(0);
    }

    /* ---main task process--- */
    Mat frame;
    VideoCapture cap;
    vector<unsigned char> inImage;  
    /* open camera */
    cap.open(0);
    if (!cap.isOpened()) 
    {
        cerr << "ERROR! Unable to open camera\n";
        return -1;
    }
    printf("open camera success\n");
    printf("======waiting for client's apple request======\n");

    if( (connfd = accept(listenfd, (struct sockaddr*)NULL, NULL)) == -1){
        printf("accept socket error: %s(errno: %d)",strerror(errno),errno);
        exit(0);
    }
    
    char cok[1]={0x55};
    char cokstart[1]={0};
    char j=0;
    int sizelen=0;
    int sizejpg=0;
    
    for (;;)
    {
        /* read one frame */
        cap.read(frame);
        /* check if we succeeded */
        if (frame.empty()) {
            cerr << "ERROR! blank frame grabbed\n";
            break;
        }
        /* stop display after get key press */
        if(waitKey(5)>=0)
            break;

        /* get trigger from client's command */
        if (cok[0]==0x55){
            cok[0]=0;
            //printf("read one frame!\n");
            /* encode frame to JPG data */
            imencode(".jpg",frame,inImage);  
            /* get length of jpg */
            int datalen=inImage.size();
            /* prepare char to save jpg data */
            unsigned char *msgImage=new unsigned char[datalen]; 
            
            unsigned char msgLen[4];
            msgLen[0]=datalen >> 24;
            msgLen[1]=datalen >> 16;
            msgLen[2]=datalen >> 8;
            msgLen[3]=datalen;
            //printf("datalen=%x\n",datalen);
            /* send lenght to client first */
            sizelen=send(connfd,msgLen,4,0);
            //printf("sizelen:%x",sizejpg);

            /* put vector data to char */
            for(int i=0;i<datalen;i++)  
            {  
                    msgImage[i]=inImage[i];  
            } 
            /* get lenght response ack from client */
            recv(connfd,cokstart,1,0);
            if(cokstart[0] == 0x33)
            {
                vector<char>vec;
                Mat img_decode;
                string filename="";
                /* decode than save display to save to file. This is optional function */
                cokstart[0]=0x0;
                /* put data to vector */
                for(int i=0;i<datalen;i++)
                {
                    vec.push_back(msgImage[i]);
                }
                /* decode JPG data */
                img_decode =imdecode(vec,CV_LOAD_IMAGE_COLOR);
                j++;
                /* display JPG data */
                imshow("serpic",img_decode);
                /* save JPG data to files */
                filename="sevpic"+int2string(j)+".jpg";
                imwrite(filename,img_decode);

                /* send data to client */
                sizejpg=send(connfd,msgImage,datalen,0);
                printf("sizejpg:%x",sizejpg);
                usleep(10000);
                /* get response ack from client then can send the next frame*/
                recv(connfd,cok,1,0);
            }
    
        }

    }
    /* if get key press than break display and stop the socket connection */
    close(listenfd);
    return 0;
}
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末望忆,一起剝皮案震驚了整個濱河市罩阵,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌启摄,老刑警劉巖稿壁,帶你破解...
    沈念sama閱讀 219,039評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件窒所,死亡現(xiàn)場離奇詭異,居然都是意外死亡篙梢,警方通過查閱死者的電腦和手機淳衙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來晾捏,“玉大人,你說我怎么就攤上這事《遣颍” “怎么了?”我有些...
    開封第一講書人閱讀 165,417評論 0 356
  • 文/不壞的土叔 我叫張陵界拦,是天一觀的道長吸申。 經(jīng)常有香客問我,道長享甸,這世上最難降的妖魔是什么截碴? 我笑而不...
    開封第一講書人閱讀 58,868評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮蛉威,結果婚禮上日丹,老公的妹妹穿的比我還像新娘。我一直安慰自己蚯嫌,他們只是感情好哲虾,可當我...
    茶點故事閱讀 67,892評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著择示,像睡著了一般束凑。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上栅盲,一...
    開封第一講書人閱讀 51,692評論 1 305
  • 那天汪诉,我揣著相機與錄音,去河邊找鬼谈秫。 笑死扒寄,一個胖子當著我的面吹牛拴签,可吹牛的內容都是我干的。 我是一名探鬼主播旗们,決...
    沈念sama閱讀 40,416評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼蚓哩,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了上渴?” 一聲冷哼從身側響起岸梨,我...
    開封第一講書人閱讀 39,326評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎稠氮,沒想到半個月后曹阔,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,782評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡隔披,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,957評論 3 337
  • 正文 我和宋清朗相戀三年赃份,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片奢米。...
    茶點故事閱讀 40,102評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡抓韩,死狀恐怖,靈堂內的尸體忽然破棺而出鬓长,到底是詐尸還是另有隱情谒拴,我是刑警寧澤,帶...
    沈念sama閱讀 35,790評論 5 346
  • 正文 年R本政府宣布涉波,位于F島的核電站英上,受9級特大地震影響,放射性物質發(fā)生泄漏啤覆。R本人自食惡果不足惜苍日,卻給世界環(huán)境...
    茶點故事閱讀 41,442評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望窗声。 院中可真熱鬧相恃,春花似錦、人聲如沸嫌佑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽屋摇。三九已至揩魂,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間炮温,已是汗流浹背火脉。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人倦挂。 一個月前我還...
    沈念sama閱讀 48,332評論 3 373
  • 正文 我出身青樓畸颅,卻偏偏與公主長得像,于是被迫代替她去往敵國和親方援。 傳聞我的和親對象是個殘疾皇子没炒,可洞房花燭夜當晚...
    茶點故事閱讀 45,044評論 2 355

推薦閱讀更多精彩內容