Category Archives: Windows

Installing OpenCV

So tinkering with OpenCV the past day has been fun.  This past summer, a co-worker and I made an application to crop images and resize them automatically to speed up booking at the jail we work at.

The first problem was face detection.  To create a method, we first invert the image.  Then run a line from left to right until the background color changes.  Do the same thing from right to left and then find the center.  Do that several times through the picture would lead us to a good center location for the face.

The second problem was that we did all this with Windows API/GDI.  These methods were very low level and difficult to run simple methods on.

For some reason, we never found OpenCV until reading a slashdot article last night.  This library is awesome for face detection and other visual work.  I use a Linux box at home and the work computers use Windows, so I like that code can be compiled with only changes to the compiler going between each computer.

Installation

The install in linux was very easy.  Ubuntu has great documentation for installing anything with apt.  Since I’m using Mint 12 (gotta get away from Gnome 3!), I was able to follow this guide.

For Windows, it was a bit more tricky.  I read guides walking me through CMake and such.  Fortunately, I found that OpenCV 2.0’s installer does not need to be compiled, just extracted.  Using this guide I was able to get it work.  To simplify things, I’ve put two zips on my server for anyone to use.

  1. OpenCV_INSTALL.zip has the installer for OpenCV 2.0, CMake guide for those using Visual C++, and a sample codeblocks project.
  2. OpenCV_DONE.zip includes the extracted source and a sample codeblocks project.

Let me know if you have any issues.  Remember, for the codeblocks project to compile, you’ll have to sent compiler search directory to [src]/include/opencv and the linker search directory to [src]/lib

Enjoy!

wxWidgets and ODBC…

Since wxWidgets > 2.8 has dropped wxODBC, I decided to learn how to use sql.h on my own.  I made a simple program to retrieve and print data in C for the command line and everything worked well.  Unfortunately, when I placed this code in my wxWidgets GUI program, it failed.  This was due to wx being unicode, so I had a whole world of learning on how to make sql.h talk with wx.  I’ve outlined the steps to make this work:

With ODBC, sql.h can work with unicode, the functions are the same, but different variables are sent.  WX defines as Unicode (as it’s usually compiled) and ODBC will map the function to the unicode variant.  For example, in a C++ program with #define UNICODE 1, such as WX, SQLDriverConnect will map to SQLDriverConnectW, the unicode variant.  The other option is SQLDriverConnectA which will allow ANSI variables.  Most of the functions you’ll need have an ‘A Variant’, which is what I’ll refer to the functions ending in A.

To Send Data:

  1. Cast your variable as a SQLWCHAR pointer.
  2. Set a string to that pointer, type cast the string too.
  3. Use the functions of ODBC that end with an A.
  4. Send that function a variable type cast as (SQLCHAR*).
SQLWCHAR *connStr;
connStr = (SQLWCHAR*)"DSN=testDB;";
SQLDriverConnectA(dbc, NULL, (SQLCHAR*)connStr, SQL_NTS,
    (SQLCHAR*)outstr, sizeof(outstr), &outstrlen,
     SQL_DRIVER_COMPLETE);

To Return Data:

  1. Do the same steps.
SQLWCHAR colName[256];
SQLDescribeColA(hstmt, i+1, (SQLCHAR*)colName, 255, &colNameLen,
      &dataType, &colSize, &numDecimalDigits, &allowsNullValues);

Convert SQLWCHAR to wxString:

  1. Use wxString’s PrintF() function and interpret the variable with a capital S.
SQLWCHAR colName[256];
wxString test;
test.PrintF(_("Column Name: %S"),colName);

Convert wxString to SQLWCHAR:

  1. Declare your buffer variable as SQLCHAR array.
  2. Cycle through each char in wxString and assign to your SQLCHAR array.
  3. Add a null value on the end (so SQL_NTS knows to stop!)
  4. Typecast the variable as a pointer in send.
wxString send = wxT("SELECT * FROM master");
SQLCHAR sqlTest[1024];
unsigned int j;
for(j=0;j<send.Len();j++) {
sqlTest[j] = send[j];
}
sqlTest[send.Len()] = _T('\0');

SQLPrepareA(hstmt, (SQLCHAR*)sqlTest, SQL_NTS);

Disappointment with IE.

A pivotal question in development is whether to use new technology or not. HTML5 and CSS can make great pages but Internet Explorer, being a huge portion of the browsers used, does not handle these except in the most recent versions. A quick google search led me to this page which had a great script to work with this problem. The work around is to create new elements to match HTML5. The detailed analysis is located in the link above.

<!--[if IE]-->
	<script type="text/javascript">
		(function(){
			var html5elmeents = "address|article|aside|audio|canvas|command|datalist|
				details|dialog|figure|figcaption|footer|header|hgroup|
				keygen|mark|meter|menu|nav|progress|ruby|section|
				time|video".split('|');
			for(var i = 0; i < html5elmeents.length; i++){
			document.createElement(html5elmeents[i]);
			}
		}
	)();
	</script>
<!--[endif]-->

EDIT: Got the page looking like I want it in IE, Firefox and Chrome/Safari but found the above script was not needed.  I surrounded my HTML5 elements (<header>, <footer>, and <nav>) with <div> tags that include the desired HTML5 element.  This makes for an easy move to HTML5 when it’s more broadly implemented. Example:

<div class="footer">
	<!-- Include the same class name only if you want CSS styling specific to the footer -->
	<footer class="footer">This is my footer text.</footer>
</div>
.footer {
	position: absolute;
	background-color: black;
}

NCOER Spreadsheet – Done

Okay, so I’ve updated my code and I’m ready to release to the world my NCOER speardsheet.  Here’s a quick tutorial on how to use it.

  1. Download the Excel 2007 or Excel 2003 version. (Right Click and Save As)
  2. Ensure that you have enabled macros [ Office 2007 ] or [ Office 2003 ] for your MS Excel.
  3. Open the file you downloaded.
  4. Enter the unit you need the report for in the textbox on the left.
  5. Click Update
  6. It will prompt you for your AKO Username/Password to access the data.
  7. Wait a short time and it will automatically load and filter.
  8. Print or export the data as needed.

And that’s it.  I know military types read this blog (proven through the Open XFDL project) so please comment and let me know your opinion!

NCOER Spreadsheet

Last week, I complained about how bulky VBA (Visual Basic for Applications) can be.  My current project is to create a spreadsheet to keep track of upcoming NCOERs.  This is an easy task in anything but the most used and abused application the admin personnel in the Army use, Microsoft Excel.  Now, the data is easy enough to pull once you get an SSL connection with this website (to access you need to use an AKO Username/Password.)  The Interactive Web Response System will allow you to pull data on any past, due or current NCOERS (Evaluations).  This is great as I can track our evaluations as they move up the chain and will see when they are late.  Unfortunately, the web designers have only sorted the information by last name.

So, my basic program is complete.  I can make a connection (fortunately, MSXML6.0 makes an easy post request to an SSL website… something that if using Python, is not an easy task.)  It would appear that it is utilizing Internet Explorer’s library for the connection.  Once the connection is made and the data is loaded, then I parse.  Here is where VBA gets bulky.  Fortunately, I can use a reference to VBScript’s RegEx object, but it is far from being as complete as say, any other regex engine in any other language.  On top of that, parsing text through splits and such is an amazing pain.  Here’s an example.

Python:

import re
test = 'A simple "test of the languages" will show how bad VBA is!'
a = re.findall(re.compile(r'".*"',re.I),test)
print "Result = %s" % a[0]
## Result = "test of the languages"

VBA:

Private Sub CommandButton1_Click()
    ' must include Microsoft VBScript Regular Expressions 5.5 in references
    Dim re As New RegExp
    Dim testing As Variant
    Dim test As String
    ' to escape quotes "" can be used or chr(34).
    ' unbelievably, chr(34) is easier to read than ""
    test = "A simple " & Chr(34) & "test of the languages" & Chr(34) & " will show how bad VBA is!"
    re.Pattern = Chr(34) & ".*" & Chr(34)
    re.IgnoreCase = True
    Set testing = re.Execute(test)
    Range("A1").Value = "Result = " & testing(0)
    ' Result = "test of the languages" in "A1"
End Sub

See the difference?  I know it’s pretty close but keep in mind, this is a single line of text.  Multiple lines, large text files, etc. can be horrendous.  What in the world is left, mid and right anyhow?  I know 90% of this is that I refuse to touch this language if I can avoid it but still, this is ridiculous!!

Microsoft Access : XFDL Viewer – Introduction

I know, I said it yesterday that it is rare that I develop on Windows, but this is a long promised application.  In 2007, my unit administrator (in the U.S. Army Reserves) suggested code that would allow batch loading XFDL forms from MS Access.  Due to the scope of the Apps 4 The Army project, I was limited to using a web application.  Now that the project is submitted and done, I am free to do my original plan, which is code to do the same process in MS Access.

Starting this today, I realized how much I hate doing Visual Basic.  Particularly, VBA is very painful!!  It’s not that the language is bad but it just always feels bulky and pieced together to me.  It seems to lack the professionalism of C/C++ and the flow of Python.  But, I may be alone in that.

I have a question for my readers though. Would anyone have an interest in seeing this project on SourceForge?  The Apps 4 the Army project is no longer my intellectual right, but a desktop application, a MS Office Plugin, etc… that’s all good to make public.  So let me know, if I get readers saying we’d like to help; then I will happily move this project to SourceForge!

Fern Screensaver : Part 3

Today, I had no Mac with me to work on my screensaver in Objective-C.  As you can see in my previous post, I used my python program and wrote it in C for SDL that works on either Windows or Linux.  Now, the basic principle is the same, I just need to output that location to the correct pixel plot method to use other systems.  I thought, since I was on Windows all day, I might as well use that to make the screensaver using Windows API.

I’ve had some use of Window’s API before to make a Breakout game for my children.  It is rustic at times but works.  I decided to not mess with OpenGL today and just use Win32 API and GDI methods.  Below you will find my complete source code and a link to download this screensaver.  Once downloaded, save it in C:\WINDOWS\System32\ and it will appear on your personalization menu.

A quick note before the code, for those unfamiliar with Windows API… there’s a lot of goobly gook here that looks scary.  It’s really not that bad but here’s the meat of the project:

  • Lines 8-34 are the same variables we’ve seen before.
  • Lines 36-40 are a ‘dot()’ method I made to clean the code (slightly).
  • After Line 42:
    • WM_CREATE is called on the start of the program.
    • WM_DESTROY is called on the completion of the program.
    • WM_PAINT is used to paint to the screen.
      • Here you see the same math as before until lines 78-82.
      • At Lines 78-82, I’m using Win32 API to create a color brush and paint it with the dot method.
    • WM_TIMER is called every millisecond in this program, it keeps the loop going.
      • InvalidateRect() will force a WM_PAINT message.
  • Everything that follows is not really applicable as it just meets the demands of the Screensaver library.

If you would like to try out this screen saver, download from this link and save the file to your C:/WINDOWS/system32/ folder.  Let me know how it works for you!

#define WINDOWS_LEAN_AND_MEAN
#include <windows.h>
#include <scrnsave.h>

#define TIMER 1

// VARIABLES
float mat[4][7] = {
    {0.0,0.0,0.0,0.16,0.0,0.0,0.01},
    {0.85,0.04,-0.04,0.85,0.0,1.6,0.85},
    {0.2,-0.25,0.23,0.22,0.0,1.6,0.07},
    {-0.15,0.28,0.26,0.24,0.0,0.44,0.07}
};
// constant sets
float xa = -5.5;
float xb = 6.5;
float ya = -0.5;
float yb = 10.5;
// x and y to be altered
float x = 0.0;
float y = 0.0;
// screen/image size
int imgx = 128;
int imgy = 128;
// floats for math fulction
float p = 0.0;
float x0 = 0;
float jx = 0;
float jy = 0;
// variables to control function
int i = 0;
int k = 1;
int end = imgx*imgy;
int done = 0;

void dot(HDC hdc, HBRUSH whtBr, int x, int y) {
        SelectObject(hdc, whtBr);
            Rectangle(hdc, x-2, y-2, x+1, y+1);
        DeleteObject(whtBr);
}

LRESULT WINAPI ScreenSaverProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
    static HDC hdc;
    //static HGLRC hrc;
    PAINTSTRUCT ps;
    HBRUSH whtBr;
    static RECT rect;
    switch(message) {
        case WM_CREATE:
            GetClientRect(hwnd,&rect);
            imgx = rect.right;
            imgy = rect.bottom;
            int ret = SetTimer(hwnd, TIMER, 1, NULL);
            if(ret == 0)
                MessageBox(hwnd, "Could not set Timer", "ERROR", MB_OK);
            break;
        case WM_DESTROY:
            KillTimer(hwnd,TIMER);
            PostQuitMessage(0);
            break;
        case WM_PAINT:
            k++;
            p = (float) rand()/RAND_MAX;
            if(p <= mat[0][6])
                i = 0;
            else if(p <= (mat[0][6]+mat[1][6]))
                i = 1;
            else if(p <= (mat[0][6]+mat[1][6]+mat[2][6]))
                i = 2;
            else
                i = 3;
            x0 = ((x*mat[i][0])+(y*mat[i][1])+mat[i][4]);
            y = (x*mat[i][2]+y*mat[i][3]+mat[i][5]);
            x = x0;
            jx = ((x-xa)/(xb-xa)*(imgx-1));
            jy = (imgy-1)-(y-ya)/(yb-ya)*imgy-1;
            // Paint it
            whtBr = CreateSolidBrush(RGB(255,255,255));
            hdc = BeginPaint(hwnd, &ps);
                dot(hdc, whtBr, (int)jx, (int)jy);
            EndPaint(hwnd, &ps);
            ReleaseDC(hwnd, hdc);
            if(k == end) {
                Sleep(5);
                done = 1;
            }
            break;
        case WM_TIMER:
            if(done == 0)
                InvalidateRect(hwnd, NULL, FALSE);
            else {
                InvalidateRect(hwnd, NULL, TRUE);
                k = 0;
                done = 0;
            }
            break;
        default:
            return DefScreenSaverProc(hwnd, message, wParam, lParam);
        }
    return 0;
}

BOOL WINAPI ScreenSaverConfigureDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) {
    //return FALSE;}
    switch(message) {
        case WM_INITDIALOG:
            //get configuration from the registry
            return TRUE;
        case WM_COMMAND:
            switch(LOWORD(wParam)) {
                case IDOK:
                    //write configuration
                    EndDialog(hDlg, LOWORD(wParam) == IDOK);
                    return TRUE;
                case IDCANCEL:
                    EndDialog(hDlg, LOWORD(wParam) == IDOK);
                    return TRUE;
            }
    }
    return FALSE;
}

BOOL WINAPI RegisterDialogClasses(HANDLE hInst) {
    return TRUE;
}

Just a note, this is the rare time you will find me messing with Windows.

Violating IT Policy!

So, I work as a social worker and we are not expected to do much more than document with our computers. For job security reasons, I use my hobby programming in work to make the workplace more efficient and ensure that I have a job tomorrow! There are some problems with this, most notably, we are not setup to do programming. So I’m going to list my favorite tricks to get setup at work.

First of all, although we work through a company ethernet connection; we do have some flexibility. For one, I read the IT Policy and it specifically states I cannot install an executable onto the harddrive. Well, problem easily solved, I have a flash drive, so in comes a website for portable applications.  Here’s the applications I use the most.

*        GOOGLE CHROME

Google Chrome is a great browser.  It’s ability to interpret javascript leaves IE# in the dust!  As for it’s portability, just like most of these, just run the executable and install it to your flash drive (or if you want a little more speed and less portability, your harddrive).  Now, Google Chrome works great right out of the box, except one thing.  It’s flash needs to be updated.  Fortunately, this is easy to solve and there are only a few steps.

  1. Get FlashPlayer XPI for Windows.
  2. Rename the *.xpi to *.zip and copy flashplayer.xpt and NPSWF32.dll
  3. Paste those two files into <install directory>/App/Chrome-bin/<version>/ directory.  Replace install directory with where you installed the application and version with the folder that is your version number.

**            NOTEPAD++

This stuff is simple, but I thought I’d post a link for the plugins.  These are easy to install, plugins go in the \Plugins\ folder, configuration files go in the \Plugins\Config\ and documentation goes in \Plugins\Doc\. Here are my favorite plugins:

***   BOA CONSTRUCTOR

For this to work, you’ll need Portable Python which installs similar to most things but it altered file associations and so I just extracted it and then it runs fine.  You’ll also want to install wxPython which is a module for python located on the Portable Python Page.  For Boa Constructor, download the file and install it on a computer of your own.  From there it copies onto the flash drive just fine, just make sure to update the settings for your main python exectuable since it won’t be in the computer’s path.

****       CODEBLOCKS

CodeBlocks is another program that will copy straight from the computer to your flash drive to make it portable.  The real trick is getting paths set and configuring WX if you’re interested in rapid development of GUI’s in C.  So here’s the quick run through.  For paths, I struggled with this on my work computer but it will not read paths that have a space.  It sees that space as the end of your path, so when setting a path for a library, for example WX, make sure you store that in a location that does not have a space in the path.  As for configuring WX, here’s what I did.  I went to the WX Pack site and got the package, which is great.  No need to compile or anything, does it all on it’s own with a directory to link your CodeBlocks library to, just be aware, this will take a lot of space on your flash drive, but with all of these things, you can always store them locally if you are daring that much against your local IT Department!

*****          CYGWIN

The biggest pain and the best program to have for avid Linux users.  This site makes a great tutorial on how to do this.  And rather than reiterating this, I’ll add my own changes.  The biggest thing was I changed the startup script and then linked that script on my desktop.  The first thing to do is to install Cygwin on your flash drive, be aware it may not install all the programs you want.  I did it three times before it all worked.  Then you have to mount the drive as you cannot do this or it will write to the registry.  As for my script, here’s what I wrote:

;rem creating a startup script
@echo off
:: clear
cls

:: locate directory
echo Locating directory...
for /F %%A in ('cd') do set WD=%%A
:: create path
echo Setting Path...
set path=%WD%\bin;%path%
set SHELL=/bin/bash
set CYGWIN=codepage:437
set HOME=/home/zbert
:: mount fs
echo Mounting File System...
bin\mount -bfu %WD%/ /
bin\mount -bfu %WD%\bin /usr/bin
bin\mount -bfu %WD%\lib /usr/lib
:: login
echo Logging in...
echo.
echo.

if "%1" == "" GOTO noopt
	if "%1" == "c" goto cmd
	if "%1" == "-c" goto cmd
	if "%1" == "--cmd" goto cmd
	if "%1" == "h" goto help
	if "%1" == "-h" goto help
	if "%1" == "--help" goto help
	echo  [*] ERROR: Unrecognized option.
	goto usage

:usage
echo usage: cygwin [c^|h^|-c^|-h^|--cmd^|--help]
goto help

:help
echo.
echo          Portable Cygwin Loader v1.0
echo.
echo     Commands:            *Run normal with no options.
echo        c ^| -c ^| --cmd     Run in Command Prompt.
echo        h ^| -h ^| --help    Display Help Message
echo.
echo        Copyright Skelton Computers © 2009
echo.
goto end

:cmd
echo cls > bin\bash -l -i
GOTO end

:noopt
bin\bash -l -i
GOTO end

:end
set path=%WD%\bin;%path%
@echo on