opencv保存内存位图数据到文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <opencv2/opencv.hpp>
 
#ifdef _DEBUG
#pragma comment(lib, "opencv_highgui249d.lib")
#pragma comment(lib, "opencv_core249d.lib")
#pragma comment(lib, "opencv_calib3d249d.lib")
#pragma comment(lib, "opencv_imgproc249d.lib")
#else
#pragma comment(lib, "opencv_highgui249.lib")
#pragma comment(lib, "opencv_core249.lib")
#pragma comment(lib, "opencv_calib3d249.lib")
#pragma comment(lib, "opencv_imgproc249.lib")
#endif
 
Mat mat(iHeight, iWidth, CV_8UC3, pData);
Mat yuvMat;
cvtColor(mat, yuvMat, CV_RGB2YUV);
imwrite(path, yuvMat);

No such method QQuickText::setText(QString)

1
bool bRet = QMetaObject::invokeMethod(textLabel, "setText", Q_ARG(QString, "world hello"));

执行这句会报如下错误:

QMetaObject::invokeMethod: No such method QQuickText::setText(QString)

原因是在QQuickText对应的头文件,比如在C:\Qt\5.6.3\msvc2013\include\QtQuick\5.6.3\QtQuick\private\qquicktext_p.h中,setText方法定义前没有Q_INVOKABLE宏。

正确调用QQuickText::setText的方式是:

1
textLabel->setProperty("text", "hi, bingo");

std function 调用成员函数的两种方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <functional>
 
class Test124 {
public:
	int Sum(int x, int y) {
		return x + y;
	}
};
 
int main()
{
	Test124 testObj;
 
	// functional1 can be defined using 'auto' keyword instead
	std::function<int(int, int)> functional1 = std::bind(&Test124::Sum, testObj,
		std::placeholders::_1, std::placeholders::_2);
	int result1 = functional1(1, 2);
 
	// functional2 can not be defined using 'auto' keyword instead
	std::function<int(Test124, int, int)> functional2 = &Test124::Sum;
	int result2 = functional2(testObj, 1, 2);
 
	return 1;
}

ON_SCOPE_GUARD

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
40
41
42
class ScopeExit {
public:
	ScopeExit() = default;
 
	ScopeExit(const ScopeExit&) = delete;
	void operator=(const ScopeExit&) = delete;
 
	ScopeExit(ScopeExit&&) = default;
	ScopeExit& operator=(ScopeExit&&) = default;
 
	template <typename F, typename... Args>
	ScopeExit(F&& f, Args&&... args) {
		func_ = std::bind(std::forward<F>(f), std::forward<Args>(args)...);
	}
 
	~ScopeExit() {
		if (func_) {
			func_();
		}
	};
 
private:
	std::function<void()> func_;
};
 
#define _SCOPE_CONCAT(a, b) a##b
#define _SCOPE_MAKE_SCOPE_(line) ScopeExit _SCOPE_CONCAT(defer, line) = [&]()
 
#undef ON_SCOPE_GUARD
#define ON_SCOPE_GUARD _SCOPE_MAKE_SCOPE_(__LINE__)
 
int main()
{
	FILE* fp = fopen("d:/aa.txt", "w+");
 
	ON_SCOPE_GUARD {
		fclose(fp);
	};
 
	fprintf(fp, "hello, file system.\n");
	return 1;
}

非控制台程序中显示控制台

1
2
3
4
5
6
7
8
9
10
11
void init()
{
	AllocConsole();
	freopen("CONIN$", "r+t", stdin);
	freopen("CONOUT$", "r+t", stdout);
}
 
void fini()
{
	// FreeConsole();
}

HWND绑定用户数据

1
2
3
4
5
6
7
hWnd = CreateWindow(...);
SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)12345);
 
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	LONG_PTR pData = GetWindowLongPtr(hWnd, GWLP_USERDATA);
	...

sys/cdefs.h: No such file or directory

有一种情况是系统编译器是arm-linux-gnueabihf-gcc,而软件编译需要arm-linux-gnueabi-gcc,这样/usr/include下需要的是arm-linux-gnueabi头文件目录而非arm-linux-gnueabihf目录,所以需要手动指定,比如在cmake的脚本中:

1
2
3
4
5
SET(CMAKE_C_COMPILER "arm-linux-gnueabihf-gcc")
SET(CMAKE_CXX_COMPILER "arm-linux-gnueabihf-g++")
SET(CMAKE_SYSTEM_PROCESSOR "armv7-a_hardfp")
add_definitions(-I/usr/include/arm-linux-gnueabihf)
add_definitions(-D__ARM_PCS_VFP)

yuv nv12图像保存颜色偏紫

如果resize先于cvtColor做,

1
2
3
4
Mat imgYUV = Mat(yuv_info.height * 3 / 2, yuv_info.width, CV_8UC1, yuv_data);
resize(imgYUV, imgYUV, Size(imgYUV.cols / 4, imgYUV.rows / 4), 0, 0, INTER_LINEAR);
Mat read_image_0;
cvtColor(imgYUV, read_image_0, CV_YUV2BGR_NV12);

保存的结果图像会偏紫,看上去蓝色或红色都变成了紫色,原因是resize把nv12格式中的U分量和V分量合并了。正确写法如下:

1
2
3
4
5
Mat imgYUV = Mat(yuv_info.height * 3 / 2, yuv_info.width, CV_8UC1, yuv_data);
Mat read_image_0;
cvtColor(imgYUV, read_image_0, CV_YUV2BGR_NV12);
resize(read_image_0, read_image_0, Size(read_image_0.cols / 4, read_image_0.rows / 4), 0, 0, INTER_LINEAR);
imwrite("/tmp/test.jpg", read_image_0);

placement new

代码直接在gcc里是可以编译通过的,在vc里编译,注意,如果是将例子代码加到MFC程序里,要注释掉源码中的DEBUG_NEW:

1
2
3
4
5
/*
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
*/

代码如下:

Read more