python socket编程 ws2tcpip_python opencv图片编码为h264文件的实例

该博客介绍了如何使用Python结合OpenCV和C++动态库hik_client.dll,将图片编码为H264格式的文件。通过创建线程、设置回调函数,实现图片的读取、编码和发送,同时展示了C++动态库中处理图像编码的相关函数。
摘要由CSDN通过智能技术生成

python opencv图片编码为h264文件的实例

发布时间:2020-09-14 05:15:52

来源:脚本之家

阅读:104

python部分

#!/usr/bin/env Python

# coding=utf-8

from ctypes import *

from PyQt5.QtCore import *

from PyQt5.QtGui import *

from PyQt5.QtWidgets import *

import time

import numpy as np

import cv2

import struct

import datetime

from numba import jit

import os

cam_dict={}

class CamInfo:

def __init__(self, cam_no=0,deviceid="default",cam_name="default"):

self.cam_no = cam_no

self.deviceid = deviceid

self.cam_name = cam_name

@jit

def trans(data,size,height,width):

bbb = string_at(data,size)

nparr = np.fromstring(bbb, np.uint8)

r = nparr.reshape(height,width, 3)

return r

def str2char_p(str_v):

pStr = c_char_p( )

pStr.value = str_v

return pStr

def callb_stream(data,size,cam_no,height,width):

r = trans(data, size,height,width)

r = cv2.cvtColor(r, cv2.COLOR_RGB2BGR)

counter = datetime.datetime.now().strftime('%Y%m%d_%H%M%S_%f')

# print(1, counter)

cv2.imshow(str(cam_no), r)

cv2.waitKey(1)

def callb_camerainfo(cam_no,camera_info,camera_info_size):

# print(cast(camera_info,c_char_p).value)

# print(str(cast(camera_info, c_char_p).value))

bbb = string_at(camera_info, camera_info_size)

info=str(bbb,encoding="utf-8").split(",")

cam_dict[cam_no]= CamInfo(cam_no,info[1],info[2])

print("camerainfo",cam_dict[cam_no].cam_no,cam_dict[cam_no].cam_name,cam_dict[cam_no].deviceid)

class Mythread(QThread):

# 定义信号,定义参数为str类型

breakSignal = pyqtSignal(str,list)

def __init__(self, parent=None):

super().__init__(parent)

# super(Mythread, self).__init__()

def callb_error(self, err_type, cam_no, msg_no, msg_level, msg_txt, msg_txtlen):

print("myerror", err_type, cam_no, msg_no, msg_level, msg_txt, msg_txtlen)

def run(self):

dll = CDLL(r"./hik_client.dll")

width=60

height=40

dll.pre_encode.restype = c_void_p

ret=dll.pre_encode(width,height)

ret=cast(ret,c_void_p)

for i in range(20000):

n=i%200+1

img=cv2.imread("bmp/"+str(n)+".bmp")

len = img.shape[0] * img.shape[1] * img.shape[2]

# img=np.transpose(img,(1, 0, 2))

# b, g, r = cv2.split(img)

# b = b.reshape(-1)

# g = g.reshape(-1)

# r = r.reshape(-1)

# b = np.append(b, g)

# img = np.append(b, r)

img = img.reshape(-1)

# b, g, r = cv2.split(img)

# b = b.reshape(-1)

# g = g.reshape(-1)

# r = r.reshape(-1)

# b = np.append(b,g)

# img = np.append(b, r)

INPUT = c_int * len

# 实例化一个长度为2的整型数组

input = INPUT()

# 为数组赋值(input这个数组是不支持迭代的)

for i in range(len):

input[i] = img[i]

# bytes(aaaa, encoding="utf-8")

a = dll.push_rtsp(input,len,ret)

QCoreApplication.instance().quit()

# print("encode_ok",i)

# b = string_at(a, 1280*720*3)

# print(b)

# nparr = np.fromstring(b, np.uint8)

# # print(nparr[-10:-1],min(nparr),max(nparr))

# img_decode = cv2.imdecode(nparr, cv2.IMREAD_COLOR)

# # if img_decode:

# cv2.imshow("sadf", img_decode)

# # cv2.imwrite(str(index)+".jpg", img_decode)

# cv2.waitKey(0)

#

#

#

#

# ErrorCall = CFUNCTYPE(c_void_p, c_int, c_int, c_int,c_int,c_char_p,c_int)

# error_callback = ErrorCall(self.callb_error)

# dll.set_callback(error_callback)

# CamCall = CFUNCTYPE(c_void_p, c_int, c_char_p,c_int)

# caminfo_CamCall = CamCall(callb_camerainfo)

# # print(b)

# if not os.path.exists("video"):

# os.makedirs("video")

# ip = b"127.0.0.1"

# port = 8888

# print("start conn")

# ret=-1

# while(ret):

# print("conn server...")

# ret= dll.tcp_init(str2char_p(ip), port)

# time.sleep(0.3)

# if (ret==0):

# type=1

# ret = dll.getcameralist(type, caminfo_CamCall)

# if (1):

# # deviceId = b"af94a68df0124d1fbf0fc2b07f3b3c3a"

# cam_no=14

# else:

# print("tcp error")

# for i in range(2000000):

# # 发出信号

# a=[i,i+1]

# self.breakSignal.emit(str(i),a)

# # 让程序休眠

# time.sleep(0.5)

if __name__ == '__main__':

app = QApplication([])

dlg = QDialog()

dlg.resize(400, 300)

dlg.setWindowTitle("自定义按钮测试")

dlgLayout = QVBoxLayout()

dlgLayout.setContentsMargins(40, 40, 40, 40)

btn = QPushButton('测试按钮')

dlgLayout.addWidget(btn)

dlgLayout.addStretch(40)

dlg.setLayout(dlgLayout)

dlg.show()

def chuli(a,s):

# dlg.setWindowTitle(s)

btn.setText(a+str(s[0]*10))

# 创建线程

thread = Mythread()

# # 注册信号处理函数

thread.breakSignal.connect(chuli)

# # 启动线程

thread.start()

dlg.exec_()

app.exit()

c++动态库部分

#include "stdafx.h"

#include "CVdll.h"

#include "SimpleLog.h"

#include

#include

#include

#include "opencv2/opencv.hpp"

#include "Ws2tcpip.h"

#include

#include

#include

#include

#include

#pragma comment(lib,"ws2_32.lib")

#include

using namespace cv;

extern "C"

{

#include "libavcodec/avcodec.h"

#include "libavformat/avformat.h"

#include "libswscale/swscale.h"

#include "libavdevice/avdevice.h"

#include "libavutil/log.h"

//#include "libavutil/imgutils.h"

};

//说明,动态库需要拷贝三个文件,否则重连会出问题

char* testchar(int plus1) {

char* str = "hello world111111";

return str;

}

char* testimg(char* data,int length) {

char* str = "hello world111111";

return str;

}

int outbuf_size = 100000;

class Rtmp_tool {

public:

int nWidth = 0;

int nHeight = 0;

AVCodecContext *c;

AVFrame *m_pRGBFrame = new AVFrame[1]; //RGB帧数据

AVFrame *m_pYUVFrame = new AVFrame[1];; //YUV帧数据

uint8_t * yuv_buff;//

uint8_t * outbuf;

SwsContext * scxt;

FILE *f = NULL;

};

void* pre_encode(int width,int height) {

Rtmp_tool *rtmp_tool;

rtmp_tool = new Rtmp_tool();

int nLen;

int fileI;

rtmp_tool->nWidth = width;

rtmp_tool->nHeight = height;

av_register_all();

avcodec_register_all();

//AVFrame *m_pRGBFrame = new AVFrame[1]; //RGB帧数据

//AVFrame *m_pYUVFrame = new AVFrame[1];; //YUV帧数据

AVCodecContext *c = NULL;

AVCodecContext *in_c = NULL;

AVCodec *pCodecH264; //编码器

//查找h364编码器

pCodecH264 = avcodec_find_encoder(AV_CODEC_ID_H264);

c = avcodec_alloc_context3(pCodecH264);

c->bit_rate = 3000000;// put sample parameters

c->width = width;//

c->height = height;//

// frames per second

AVRational rate;

rate.num = 1;

rate.den = 5;

c->time_base = rate;//(AVRational){1,25};

c->gop_size = 10; // emit one intra frame every ten frames

c->max_b_frames = 1;

c->thread_count = 1;

c->pix_fmt = AV_PIX_FMT_YUV420P;//PIX_FMT_RGB24;

//av_opt_set(c->priv_data, /*"preset"*/"libvpx-1080p.ffpreset", /*"slow"*/NULL, 0);

//打开编码器

if (avcodec_open2(c, pCodecH264, NULL)<0)

printf("不能打开编码库");

int size = c->width * c->height;

rtmp_tool->yuv_buff = (uint8_t *)malloc((size * 3) / 2); // si

关于嗅探器的源代码#include #include #include #include #include #pragma comment(lib,"ws2_32.lib") #define MAX_HOSTNAME_LAN 255 #define SIO_RCVALL _WSAIOW(IOC_VENDOR,1) #define MAX_ADDR_LEN 16 struct ipheader { unsigned char ip_hl:4; unsigned char ip_v:4; unsigned char ip_tos; unsigned short int ip_len; unsigned short int ip_id; unsigned short int ip_off; unsigned char ip_ttl; unsigned char ip_p; unsigned short int ip_sum; unsigned int ip_src; unsigned int ip_dst; }; typedef struct tcpheader { unsigned short int sport; unsigned short int dport; unsigned int th_seq; unsigned int th_ack; unsigned char th_x:4; unsigned char th_off:4; unsigned char Flags; unsigned short int th_win; unsigned short int th_sum; unsigned short int th_urp; }TCP_HDR; typedef struct udphdr { unsigned short sport; unsigned short dport; unsigned short len; unsigned short cksum; }UDP_HDR; void main(){ SOCKET sock; WSADATA wsd; DWORD dwBytesRet; unsigned int optval = 1; unsigned char *dataudp,*datatcp; int i,pCount=0,lentcp, lenudp; SOCKADDR_IN sa,saSource, saDest; struct hostent FAR * pHostent; char FAR name[MAX_HOSTNAME_LAN]; char szSourceIP[MAX_ADDR_LEN], szDestIP[MAX_ADDR_LEN],RecvBuf[65535] = {0}; struct udphdr *pUdpheader; struct ipheader *pIpheader; struct tcpheader *pTcpheader; WSAStartup(MAKEWORD(2,1),&wsd); if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP))==SOCKET_ERROR) exit(1); gethostname(name, MAX_HOSTNAME_LAN); pHostent = gethostbyname(name); sa.sin_family = AF_INET; sa.sin_port = htons(6000); memcpy(&sa.sin_addr.S_un.S_addr, pHostent->h_addr_list[0], pHostent->h_length); bind(sock, (SOCKADDR *)&sa, sizeof(sa)); if ((WSAGetLastError())==10013) exit(1); WSAIoctl(sock, SIO_RCVALL, &optval, sizeof(optval), NULL, 0, &dwBytesRet, NULL, NULL); pIpheader = (struct ipheader *)RecvBuf; pTcpheader = (struct tcpheader *)(RecvBuf+ sizeof(struct ipheader )); pUdpheader = (struct udphdr *) (RecvBuf+ sizeof(struct ipheader )); while (1){ memset(RecvBuf, 0, sizeof(RecvBuf)); recv(sock, RecvBuf, sizeof(RecvBuf), 0); saSource.sin_addr.s_addr = pIpheader->ip_src; strncpy(szSourceIP, inet_ntoa(saSource.sin_addr), MAX_ADDR_LEN); saDest.sin_addr.s_addr = pIpheader->ip_dst; strncpy(szDestIP, inet_ntoa(saDest.sin_addr), MAX_ADDR_LEN); lentcp =(ntohs(pIpheader->ip_len)-(sizeof(struct ipheader)+sizeof(struct tcpheader))); lenudp =(ntohs(pIpheader->ip_len)-(sizeof(struct ipheader)+sizeof(struct udphdr))); if((pIpheader->ip_p)==IPPROTO_TCP&&lentcp!=0){ printf("*******************************************\n"); pCount++; datatcp=(unsigned char *) RecvBuf+sizeof(struct ipheader)+sizeof(struct tcpheader); printf("-TCP-\n"); printf("\n%s\n",szDestIP); printf("\n%i\n",ntohs(pTcpheader->dport)); printf("datatcp address->%x\n",datatcp); printf("size of ipheader->%i\n",sizeof(struct ipheader)); printf("size of tcpheader->%i\n",sizeof(struct tcpheader)); printf("size of the hole packet->%i\n",ntohs(pIpheader->ip_len)); printf("\nchar Packet%i [%i]=\"",pCount,lentcp-1); for (i=0;i<lentcp;i++){ printf("\\x%.2x",*(datatcp+i)); if (i==0) printf("\"\n\""); } printf("\";\n\n\n"); for (i=0;i<lentcp;i++){ if( *(datatcp+i)=20) printf("%c",*(datatcp+i)); else printf("."); } printf("\n\n*******************************************\n"); } if((pIpheader->ip_p)==IPPROTO_UDP&&lentcp!=0){ pCount++; dataudp=(unsigned char *) RecvBuf+sizeof(struct ipheader)+sizeof(struct udphdr); printf("-UDP-\n"); printf("\n%s\n",szDestIP); printf("\n%d\n",ntohs(pTcpheader->dport)); printf("UDP%x\n",dataudp); printf("IP%i\n",sizeof(struct ipheader)); printf("UDP%i\n",sizeof(struct udphdr)); printf("%i\n",ntohs(pIpheader->ip_len)); printf("\nchar Packet%i [%i]=\"",pCount,lenudp-1); for (i=0;i<lenudp;i++){ printf("\\x%.2x",*(dataudp+i)); if (i==0) printf("\"\n\""); } printf("\";\n\n\n"); for (i=0;i<lenudp;i++){ if( *(dataudp+i)=20) printf("%c",*(dataudp+i)); else printf("."); } printf("\n\n*******************************************\n"); } } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值