Posted on 09-09-2011
Filed Under (技术) by waterlin

最近折腾得够呛,天天写代码,都没时间更新博客了。

总结一下最近碰到的两个问题,写到中文 Wiki 里了,希望对大家有点帮助。

  1. OpenCV 在 Ubuntu 11.04 平台上的编译

    最近要迁移大把工作成果到 Linux 平台,即要在 Linux 下大量地折腾与 OpenCV 相关的代码。很久没有在 Linux 上折腾了,时过境迁,同样碰到了不少问题,写成日志《OpenCV 各种安装错误汇总》

  2. Berkeley DB 数据库的操作还是蛮有技巧的,如果需要把内存里结构比较复杂的数据写到 Berkeley DB 里,我当然拥有我的技巧,以把 IplImage 数据写入到 Berkeley DB 为例,介绍我对这一技术的理解。
(0) Comments    Read More   
Posted on 02-08-2011
Filed Under (技术) by waterlin

OpenCV2.1 生成视频选择编码的 bug

最近使用 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 2008 问题

官方的 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 跳转到指定的时间,和用 DirectShow 跳转到视频指定的时间,理论上来说,应该是一样的。可是,在我这里,偏偏就出现了跳转视频位置不同的情况。而且,原始视频越长,这种误差越大。

是什么原因呢?

仔细研究了一下,我用 OpenCV 读取参数,会显示是 29 帧/秒,大约有 276168 帧;但是用 DirectShow 解码后显示为 30 帧/秒,计算后约为 268946 帧。

解码后的度量时间标准不同,也就导致了上述误差。但是,真实的原因是什么呢?

(0) Comments    Read More   
Posted on 04-04-2011
Filed Under (技术) by waterlin

今天早上碰到一个很奇怪的事情,昨天明明还能在 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.

知其然更要知其所以然,有谁知道原因的?

(0) Comments    Read More   
Posted on 15-09-2010
Filed Under (技术) by waterlin

写了一大堆的代码,要生成 C++ 类的文档及关系图怎么办呢?对,就是生成 MFC 类库示意图那样让人赏心悦目的东西。

总体来说,生成这种文档有三种思路:

  1. Doxygen 来自动生成文档

    用 Doxygen 可以跨平台,在维护代码的同时,维护文档,很方便很实用。

    如果需要生成类的关系图,可以用 Doxygen 配上 Graphviz,安装好 Graphviz 后,需要把该可执行目录添加到系统的 Path 里,这样在 Doxygen 里就可以用 Graphviz 来生成类的关系图。

    如果是在 vim, Emacs 这类文本编辑器里,则可以很自然地使用宏操作来插入 Doxygen 注释;如果是用 Visual Studio 的话呢,也是可以用 DoxyComment add-in for Visual Studio 2005 之类的东西来完成。

    用 Doxygen 来生成文档有一个要注意的地方,源代码文件的编码和 Doxygen 选用的字符编码需要一致,否则生成的文档会乱码。现在这个年代,当然是统一用 UTF-8 好一点了。

  2. 用 Visual Studio 的 Class Diagram

    MSDN 上专门有关于使用 Class Diagram 的介绍。

  3. 用 Visio 来画 UML 图,纯人肉体力活,累,难与代码同步,不推荐使用。
(0) Comments    Read More   
Posted on 29-04-2010
Filed Under (技术) by waterlin

需要测试某台机器的某个端口是否能用,从而可以使用相关的服务,可以用

telnet ip port

这种形式的命令来测试。

清屏后光标一闪一闪说明服务器该端口可连接。

(2) Comments    Read More   
Posted on 07-02-2010
Filed Under (技术) by waterlin

上新浪玩了一把微博,突然依然觉得应该试一下 Twitter,没办法,虽然上面全是老外,但是我依然对如何在中国访问 Twitter 产生了深厚的技术兴趣。

原来可以用 Dabr 来访问 Twitter,当然,最好是能搭一个 Dabr 在自己国外的服务器上

  1. 把文件解压到你的域名下,比较说 http://t.WaterLin.org 之类的;
  2. 重命令 config.sample.php 为 config.php 文件;
  3. 修改 config.php 文件里的 ENCRYPTION_KEY 为一个随机字符串,最大为 52 个字符。

这样输入你的 Twitter 帐户和密码就可以访问 Twitter 信息了。可是,我发现我对着 Dabr 依然不知道应该玩些什么。

原创文章,如转载请注明:转载自细节之锤 [ http://blog.WaterLin.org/ ]

Copyright © WaterLin.org. All rights reserved.

(0) Comments    Read More   
Posted on 20-12-2009
Filed Under (技术) by waterlin

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.

(0) Comments    Read More   
Posted on 20-12-2009
Filed Under (技术) by waterlin

如果用了 Visual Studio 2005 之类的 IDE 后,对于该类 IDE 提供的前后位置跳转功能,一定会印象很深。

Code::Blocks 也可以装上类似的插件,有一个名叫 Browse Tracker plugins 的插件集合,提供了类似的功能。

Debian/Ubuntu 下可以装上 codeblocks-contrib 这个包,然后就有了 Browse Tracker 的功能。

安装好了以后,可以先通过 Code::Blocks 的菜单 View ==> Browse Tracker ==> Setting,把 Enable BrowseMarks 选上。

默认情况下的使用:

  • 用 Alt-Left 和 Alt-Right 快捷键在编辑器堆栈 ( editor stack ) 里前后跳转;
  • 用 Alt-Up 和 Alt-Down 快捷键来在最近标记 ( marked editor positions ) 的地方跳转;
  • 需要标记一个阅读标记 ( Browse mark ),可以在需要标记的地方,按住鼠标左键一小会(默认配置是 0.2 秒),即可以在当前位置创建一个阅读标记。以后可以用 Alt + up 或 Alt + down 键来回到这里。标记后,在左边的序号里会显示为省略号 “…” 。

    原创文章,如转载请注明:转载自细节之锤 [ http://blog.WaterLin.org/ ]

    Copyright © WaterLin.org. All rights reserved.

(0) Comments    Read More   
Posted on 27-10-2009
Filed Under (技术) by waterlin

项目组如果用 SVN 来管理代码,人一多,谁都可以提交 ( check in) 代码的话,代码很快就会变得混乱不堪,永远也稳定不下来。

这个时候,可以用 SVN 的 patch 功能。我们可以根据自己修改的代码,生成一份和原来代码 diff 后的记录文件,保存下来就成了一个 patch 文件了。代码管理者通过这个 patch 文件,可以很好地观看到修改建议,从而决定是否进行提交。

如果是 TortoiseSVN 的话,要生成 patch 文件很简单,从 TortoiseSVN -> Create patch… 即可生成 patch 文件,保存为以 .patch 或 .diff 结尾的文件即可,如下图所示:

svnpatchCopyright.jpg

代码提交要使用这个 patch,只需要 TortoiseSVN -> Apply Patch… 即可。

详细的信息可以参考 TortoiseSVN 官方文档

原创文章,如转载请注明:转载自细节之锤 [ http://blog.WaterLin.org/ ]

Copyright © WaterLin.org. All rights reserved.

(0) Comments    Read More   
Posted on 08-07-2009
Filed Under (技术) by waterlin

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进行操作了。

(0) Comments    Read More