将h264流存为avi文件

使用ffmpeg存为avi和存为mp4在代码上是一样的,ffmpeg可以通过文件名后缀决定视频文件类型,以下是关键代码:

AviWriter.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#pragma once
 
class AVFormatContext;
class AVStream;
 
class AviWriter
{
public:
	int createFile(const char* filename);
	int setVideoTrack(const char* sps, int spslen, const char* pps, int ppslen, int width, int hight, int rate);
	int writeVideoSample(char* data, int datasize, bool keyframe);
	void closeFile();
 
private:
	AVFormatContext *m_fc;
	AVStream *m_avStream;
	int m_isHeaderWritten;
};

Read more

获取球机的辅码流

从编程角度讲,球机的辅码流和主码流差别就是uri,如海康的球机主码流如:

rtsp://admin:admin@192.168.1.224/1

则其辅码流为:

rtsp://admin:admin@192.168.1.224/2

那如何获取辅码流呢?

是通过onvif协议登陆球机后,获取profile列表,在列表中选择低分辨率的profile,比如宽小于1800,或者高小于1000的就可认为是辅码流,就可取出对应的uri。

webservice c++

在C++中怎么调用webservice?微软的vs里总是对webservice支持不够,其实最安心的还是用开源的gsoap,现在已经很稳定了。

网上关于使用gsoap的教程一大堆,我只说关于使用中碰到的一个问题:我在客户端已将发送的字符串转码成utf8了,通过gsoap发送过去,服务器端接收到的还是乱码,此时,只要在客户端初始化gsoap时加入:

1
2
3
4
5
struct soap soapCtx;
//注意此时不要再调用soap_init了,在上一句的构造函数中,
//gsoap自己已经调用过soap_init了。
// soap_init(&soapCtx);
soap_set_mode(&soapCtx, SOAP_C_UTFSTRING);

Android jni GetTickCount

1
2
3
4
5
6
unsigned long GetTickCount()
{
	struct timespec ts;
	clock_gettime(CLOCK_MONOTONIC, &ts);
	return (ts.tv_sec * 1000 + ts.tv_nsec / (1000 * 1000));
}

pcap-stdinc.h inline C1189

更换了pcap.h和windows.h的包含顺序后,编译出现如下错误:

warning C4005: 'inline' : macro redefinition
fatal error C1189: #error : The C++ Standard Library forbids macroizing keywords. Enable warning C4005 to find the forbidden macro.

解决方法,注释掉pcap-stdinc.h里的:

//#define inline __inline

caffe FLAGS_gpu

FLAGS_gpu直接在caffe里找定义是找不到的,它由这句定义:

DEFINE_string(gpu, ...

所以想运行device_query的命令行应该这样输入:

caffe.exe device_query -gpu all

抓屏获取QQ窗口的方法

用拷贝桌面HDC的方法抓不到QQ窗口,经试验,用键盘Print Screen键是可以抓到QQ窗口的,因此用以下方法抓屏:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
HBITMAP copyBitmap(HBITMAP hSourceHbitmap)
{
	CDC sourceDC;
	CDC destDC;
	sourceDC.CreateCompatibleDC(NULL);
	destDC.CreateCompatibleDC(NULL);
	BITMAP bm = { 0 };
	::GetObject(hSourceHbitmap, sizeof(bm), &bm);
 
	HBITMAP hbmResult = ::CreateCompatibleBitmap(CClientDC(NULL), bm.bmWidth, bm.bmHeight);
 
	HBITMAP hbmOldSource = (HBITMAP)::SelectObject(sourceDC.m_hDC, hSourceHbitmap);
	HBITMAP hbmOldDest = (HBITMAP)::SelectObject(destDC.m_hDC, hbmResult);
	destDC.BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &sourceDC, 0, 0, SRCCOPY);
 
	::SelectObject(sourceDC.m_hDC, hbmOldSource);
	::SelectObject(destDC.m_hDC, hbmOldDest);
	::DeleteObject(sourceDC.m_hDC);
	::DeleteObject(destDC.m_hDC);
 
	return hbmResult;
}
 
HBITMAP CSnapDlg::CaptureScreen()
{
	keybd_event((byte)0x2c, 0, 0x0, NULL);    //down
	keybd_event((byte)0x2c, 0, 0x2, NULL);    //up
	Sleep(500);
 
	HBITMAP hBitmap = NULL;
	if (OpenClipboard())
	{
		HBITMAP handle = (HBITMAP)GetClipboardData(CF_BITMAP);
		hBitmap = copyBitmap(handle);
 
		CloseClipboard();
	}
	return hBitmap;
}

python绘制函数图像

2D隐函数画法:

1
2
3
4
from sympy.parsing.sympy_parser import parse_expr
from sympy import plot_implicit
ezplot = lambda expr: plot_implicit(parse_expr(expr))
ezplot('x*x - y')

2D一般画法:

1
2
3
4
5
6
import matplotlib.pyplot as plt
import numpy as np
import math
t = np.arange(-1.0, 1.01, 0.01)
plt.plot(t, np.exp(t), 'r', t, np.log(1 + np.exp(t)), 'b')
plt.show()

3D一般画法:

1
2
3
4
5
6
7
8
9
10
11
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure()
ax = Axes3D(fig)
x = np.arange(-4, 4, 0.25)
y = np.arange(-4, 4, 0.25)
x, y = np.meshgrid(x, y)
z = x + y ** 2
ax.plot_surface(x, y, z, rstride = 1, cstride = 1, cmap = 'rainbow')
plt.show()

3D画法2:

1
2
3
4
5
from sympy import *
from sympy.plotting import plot3d
x, y = symbols('x y')
plot3d(x * y, -x + y, (x, -5, 5), (y, -5, 5))
plot3d((x**2 + y**2, (x, -5, 5), (y, -5, 5)), (x*y, (x, -3, 3), (y, -3, 3)))

3D画法3:

1
2
3
4
5
6
7
8
import numpy as np
from mayavi import mlab
x = np.arange(-40, 40, 0.25)
y = np.arange(-40, 40, 0.25)
x, y = np.meshgrid(x, y)
z = np.cos(np.sqrt(x**2 + y**2))
s = mlab.mesh(x,y,z)
mlab.show()

参数方程3D画法:

1
2
3
4
5
from sympy import *
from sympy.plotting import *
u, v = symbols('u v')
plot3d_parametric_line((cos(u), sin(u), u, (u, -5, 5)), (sin(u), u ** 2, u, (u, -5, 5)))
plot3d_parametric_surface((cos(u + v), sin(u - v), u - v,(u, -5, 5), (v, -5, 5)),(cos(u - v), sin(u + v), u - v,(u, -3, 3), (v, -3, 3)))

极坐标图:

1
2
3
4
5
6
7
import numpy as np
import matplotlib.pyplot as plt
ax = plt.subplot(111, polar = True)
ax.set_rlim(0, 2)
theta = np.arange(0, 2 * np.pi, 0.02)
ax.plot(theta, np.cos(theta))
plt.show()

矩阵对角化:

1
2
3
4
5
6
7
8
9
10
import numpy as np
a = [[np.cos(np.pi / 3), -np.sin(np.pi / 3)], [np.sin(np.pi / 3), np.cos(np.pi / 3)]]
c = np.linalg.eig(a)
d = c[1]
e = np.dot(np.dot(np.linalg.inv(d), a), d)
 
A = np.mat("1 -2 1; 0 2 -8; -4 5 9")
b = np.array([0, 8 -9])
x = np.linalg.solve(A, b)
y = np.linalg.det(A)

输出excel表格:

1
2
3
4
5
import os
import pandas as pd
fileNames = os.listdir("./")
df = pd.DataFrame({'no' : range(1, len(fileNames) + 1), 'filename' : fileNames})
df.to_excel('dir.xlsx')

命令行参数提示:

1
2
3
4
5
6
7
8
9
10
11
12
import click
 
@click.command()
@click.option('--times', default=1, help='times to run.')
@click.argument('name')
def runLoop(name, times = 1):
	print("name is " + name)
	for i in range(times):
		print("running {} times".format(i+1))
 
if __name__ == '__main__':
	runLoop()

字符串格式化为C语言语句:

1
2
3
str = "DEADBEEF"
for i in range(int(len(str) / 2)):
    print("0x" + str[i * 2] + str[i * 2 + 1] + ", ", end = "")

HBITMAP数据对齐

CreateDIBSection生成HBITMAP时,传入的第四个参数ppvBits即会返回指向HBITMAP图像数据的指针,访问数据里面的点会涉及到数据对齐的问题。

一般我们访问未数据对齐的点的方法是:

1
2
3
4
5
6
7
8
for (int i = 0; i < width; i++)
{
	for (int j = 0; j < height; j++)
	{
		BYTE *color3 = pvBits + (j * width + i) * 3;
		...
	}
}

但HBITMAP的数据有对齐规定,正确访问方法是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
BITMAP bm;
CBitmap cbm;
cbm.Attach(hBmp); // <- 这是HBITMAP
cbm.GetBitmap(&bm);
int pixelBytes = bm.bmBitsPixel / 8;
for (int i = 0; i < width; i++)
{
	for (int j = 0; j < height; j++)
	{
		//pData在此没给出获取方法,网上都是关联HDC来获取,不爽,
		//具体是用GetDIBits函数从HBITMAP里拷贝一份内存出来
		BYTE *color3 = pData + j * bm.bmWidthBytes + i * pixelBytes;
		DWORD byte0 = *color3;
		DWORD byte1 = *(color3 + 1);
		DWORD byte2 = *(color3 + 2);
		COLORREF color4 = (byte0 << 16) | (byte1 << 8) | byte2;
		::SetPixel(hDC, i, height - j, color4);
	}
}