最近折腾得够呛,天天写代码,都没时间更新博客了。
总结一下最近碰到的两个问题,写到中文 Wiki 里了,希望对大家有点帮助。
最近要迁移大把工作成果到 Linux 平台,即要在 Linux 下大量地折腾与 OpenCV 相关的代码。很久没有在 Linux 上折腾了,时过境迁,同样碰到了不少问题,写成日志《OpenCV 各种安装错误汇总》。
最近使用 OpenCV2.1 来生成视频,在 Windows 下碰到这样的问题:不管我用什么样的编码,都没有办法直接生成视频,并且会导致程序崩溃。代码如下:
_writer = cvCreateVideoWriter( video.c_str(),
CV_FOURCC('X','V','I','D'),
_fps,
cvSize(frameW,frameH),
isColor );
但是,如果我把编码换上 -1 选项来手工选取视频格式,则能顺利生成视频。代码如下:
_writer = cvCreateVideoWriter( video.c_str(),
-1,
_fps,
cvSize(frameW,frameH),
isColor );
这个应该是 OpenCV2.1 里的一个 Bug,换成 OpenCV2.2 就没有这个问题了。
官方的 OpenCV2.2 是在 Visual Studio 2010 下编译的二进制包,所以,当你把 OpenCV2.2 嵌入到 Visual Studio 2008 里,可以正常编译相关的代码,但是一运行,一定会提示找不到动态链接库 msvcp100d.dll 或是 msvcr100d.dll 。
这个时候,你可以把这两个 Visual Studio 2010 的动态链接库拷贝到编译好的可执行文件目录里。但是,最好的方式,是你在 Visual Studio 2008 里重新编译一下 OpenCV2.2。
有一些视频,我用 OpenCV 跳转到指定的时间,和用 DirectShow 跳转到视频指定的时间,理论上来说,应该是一样的。可是,在我这里,偏偏就出现了跳转视频位置不同的情况。而且,原始视频越长,这种误差越大。
是什么原因呢?
仔细研究了一下,我用 OpenCV 读取参数,会显示是 29 帧/秒,大约有 276168 帧;但是用 DirectShow 解码后显示为 30 帧/秒,计算后约为 268946 帧。
解码后的度量时间标准不同,也就导致了上述误差。但是,真实的原因是什么呢?
今天早上碰到一个很奇怪的事情,昨天明明还能在 Visual Studio 2008 里顺利编译的代码,今天编译的时候,就提示如下错误:
错误 171 错误的结果 -1073741819 (从"C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\mt.exe"返回)。 项目
用英文版的 Visual Studio 2008 应该是显示类似如下的错误信息:
Project : error PRJ0002 : Error result 31 returned from 'C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\mt.exe'.
这是怎么回事呢?原因我不是很清楚,但是可以用下面的方法来解决:
右键点击工程,选”属性”==>”配置属性”==>”链接器”==>”清单文件”==>”生成清单”==>设为”否”
英文版的 Visual Studio 2008 应该是如下路径:
Properties ==> Configuration Properties ==> Linker ==> Manifest File, set Generate Manifest to No.
知其然更要知其所以然,有谁知道原因的?
写了一大堆的代码,要生成 C++ 类的文档及关系图怎么办呢?对,就是生成 MFC 类库示意图那样让人赏心悦目的东西。
总体来说,生成这种文档有三种思路:
用 Doxygen 可以跨平台,在维护代码的同时,维护文档,很方便很实用。
如果需要生成类的关系图,可以用 Doxygen 配上 Graphviz,安装好 Graphviz 后,需要把该可执行目录添加到系统的 Path 里,这样在 Doxygen 里就可以用 Graphviz 来生成类的关系图。
如果是在 vim, Emacs 这类文本编辑器里,则可以很自然地使用宏操作来插入 Doxygen 注释;如果是用 Visual Studio 的话呢,也是可以用 DoxyComment add-in for Visual Studio 2005 之类的东西来完成。
用 Doxygen 来生成文档有一个要注意的地方,源代码文件的编码和 Doxygen 选用的字符编码需要一致,否则生成的文档会乱码。现在这个年代,当然是统一用 UTF-8 好一点了。
MSDN 上专门有关于使用 Class Diagram 的介绍。
需要测试某台机器的某个端口是否能用,从而可以使用相关的服务,可以用
telnet ip port
这种形式的命令来测试。
清屏后光标一闪一闪说明服务器该端口可连接。
上新浪玩了一把微博,突然依然觉得应该试一下 Twitter,没办法,虽然上面全是老外,但是我依然对如何在中国访问 Twitter 产生了深厚的技术兴趣。
原来可以用 Dabr 来访问 Twitter,当然,最好是能搭一个 Dabr 在自己国外的服务器上:
这样输入你的 Twitter 帐户和密码就可以访问 Twitter 信息了。可是,我发现我对着 Dabr 依然不知道应该玩些什么。
原创文章,如转载请注明:转载自细节之锤 [ http://blog.WaterLin.org/ ]
Copyright © WaterLin.org. All rights reserved.
Linux 下本地写代码的话,有一个 SVN 版本控制还是会好很多的。安装好 SubVersion 后,就可以直接用 svnadmin 命令来 import 一个本地的文件(以下内容摘自《Subversion 权威指南》中文版),比如说:
$ svnadmin create /var/svn/newrepos
$ svn import mytree file:///var/svn/newrepos/some/project \
-m "Initial import"
Adding mytree/foo.c
Adding mytree/bar.c
Adding mytree/subdir
Adding mytree/subdir/quux.h
路径 file:///F|/Zoundry%20Raven/var/svn/newrepos/some/project 就是你想让 svn 保存有关 svn 版本信息的目录,这样,你的目录 mytree 里的内容就提交到了代码仓库里。
然后你可以查一下是否已经提交了一份代码到所指定的路径里:
$ svn list file:///var/svn/newrepos/some/project bar.c foo.c subdir/
注意,在导入之后,原来的目录树并没有转化成工作拷贝,为了开始工作,你还是需要运行 svn checkout 导出一个工作拷贝。
原创文章,如转载请注明:转载自细节之锤 [ http://blog.WaterLin.org/ ]
Copyright © WaterLin.org. All rights reserved.
如果用了 Visual Studio 2005 之类的 IDE 后,对于该类 IDE 提供的前后位置跳转功能,一定会印象很深。
Code::Blocks 也可以装上类似的插件,有一个名叫 Browse Tracker plugins 的插件集合,提供了类似的功能。
Debian/Ubuntu 下可以装上 codeblocks-contrib 这个包,然后就有了 Browse Tracker 的功能。
安装好了以后,可以先通过 Code::Blocks 的菜单 View ==> Browse Tracker ==> Setting,把 Enable BrowseMarks 选上。
默认情况下的使用:
原创文章,如转载请注明:转载自细节之锤 [ http://blog.WaterLin.org/ ]
Copyright © WaterLin.org. All rights reserved.
项目组如果用 SVN 来管理代码,人一多,谁都可以提交 ( check in) 代码的话,代码很快就会变得混乱不堪,永远也稳定不下来。
这个时候,可以用 SVN 的 patch 功能。我们可以根据自己修改的代码,生成一份和原来代码 diff 后的记录文件,保存下来就成了一个 patch 文件了。代码管理者通过这个 patch 文件,可以很好地观看到修改建议,从而决定是否进行提交。
如果是 TortoiseSVN 的话,要生成 patch 文件很简单,从 TortoiseSVN -> Create patch… 即可生成 patch 文件,保存为以 .patch 或 .diff 结尾的文件即可,如下图所示:

代码提交要使用这个 patch,只需要 TortoiseSVN -> Apply Patch… 即可。
详细的信息可以参考 TortoiseSVN 官方文档。
原创文章,如转载请注明:转载自细节之锤 [ http://blog.WaterLin.org/ ]
Copyright © WaterLin.org. All rights reserved.
MySQL提供了C++语言的操作接口,用这个接口可以针对自己的数据库写一个C++的客户端出来,安装的方法请参看官方文档。
这个文章已经把在Visual Studio 2008里如何编写MySQL Connector C++的应用程序进行了详细的说明,此方法是针对MySQL Connector C++的安装包来介绍的。而另一篇文章则介绍了如何从MySQL Connector C++的源码包编译。
这里介绍一下Visual Studio 2005下面,用安装二进制包的方法来使用MySQL Connector C++的方法:
1) 先安装MySQL
记得要把Developer Components – C Include Files / Lib Files选上。当然,你不安装MySQL而只装这个单独的包也行,不过我还是建议在本地装一个MySQL,否则怎么测试呢?远程测试太麻烦了~~
2) 下载与Visual Studio 2005相对应的MySQL Connector C++版本
3) 在Visual Studio 2005里创建一个Win32 Console工程
File->New Project->Visual C++->Win32->Win32 Console Application
注意:”Application Settings”里的”Additional options: Precompiled header”默认是会被选上的,而我们这里,基本上可以不用这个。
4) 正确地配置工程属性
不管是Debug还是Release,都是用下面的方法设置就可以了,主要是把相关的头文件include到工程,再指定相关的动态链接库所在路径。
(1) 打开”project”->”properties”对话框,选择”configuration properties”
把MySQL Connector/C++的安装目录添加到Additional Include Directory里:
Project->Properties
Configuration Properties -> open tree view
C/C++ -> General -> Additional Include Directory
(2) 让编译器能找到MySQL Connector/C++的libraries,只要把MySQL Connector/C++安装目录里的lib/opt目录添加到搜索路径即可:
Linker -> General -> Additional Library Directories
(3) 编译器在编译的时候,让linker去链接MySQL Connector/C++的mysqlcppconn.lib库
把mysqlcppconn.lib添加到这里:
Linker -> Input -> Additional Dependencies
5) 可以试着编译下面的这段最基本的代码:
/*
examples/standalone_example_docs1.cpp
*/
/* Standard C++ includes */
#include
#include
/*
Include directly the different
headers from cppconn/ and mysql_driver.h + mysql_util.h
(and mysql_connection.h). This will reduce your build time!
*/
#include "mysql_connection.h"
#include "cppconn/driver.h"
#include "cppconn/exception.h"
#include "cppconn/resultset.h"
#include "cppconn/statement.h"
using namespace std;
int main(void)
{
cout << endl;
cout << "Running 'SELECT 'Hello World!' AS _message'..." << endl;
try {
sql::Driver *driver;
sql::Connection *con;
sql::Statement *stmt;
sql::ResultSet *res;
/* Create a connection */
driver = get_driver_instance();
con = driver->connect("tcp://127.0.0.1:3306", "root", "password");
/* Connect to the MySQL test database */
con->setSchema("test");
stmt = con->createStatement();
res = stmt->executeQuery("SELECT 'Hello World!' AS _message");
while (res->next()) {
cout << "\t... MySQL replies: ";
/* Access column data by alias or column name */
cout << res->getString("_message") << endl;
cout << "\t... MySQL says it again: ";
/* Access column fata by numeric offset, 1 is the first column */
cout << res->getString(1) << endl;
}
delete res;
delete stmt;
delete con;
} catch (sql::SQLException &e) {
cout << "# ERR: SQLException in " << __FILE__;
cout << "(" << __FUNCTION__ << ") on line " << __LINE__ << endl;
cout << "# ERR: " << e.what();
cout << " (MySQL error code: " << e.getErrorCode();
cout << ", SQLState: " << e.getSQLState() << " )" << endl;
}
cout << endl;
return EXIT_SUCCESS;
}
如果一切顺序,应该就能连上本地的MySQL进行操作了。