Browsed by
Category: Programming

Convert an OpenCV 2 Image to an Allegro 5 Image In C/C++

Convert an OpenCV 2 Image to an Allegro 5 Image In C/C++

Just a quick sample for converting an OpenCV 2 image (Mat) to an Allegro 5 image (ALLEGRO_BITMAP).

First we need to setup some things and have places to store some stuff:

#include <allegro5/allegro.h>
#include <allegro5/allegro_image.h>
#include <cv.h>
#include <highgui.h>

cv::VideoCapture video([device number/filename]);
cv::Mat frame;
ALLEGRO_BITMAP *image = al_create_bitmap([width], [height]);

Next the guts:

video >> frame;
if ( !frame.empty() ) {
	al_set_target_bitmap(image);
	al_lock_bitmap(image, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_WRITEONLY);
	for ( int y = 0; y < [height]; y++ ) {
		for ( int x = 0; x < [width]; x++ ) {
			cv::Vec3b &pixel = frame.at(y, x);
			al_put_pixel(x, y, al_map_rgb(pixel[2], pixel[1], pixel[0]));
		}
	}
	al_unlock_bitmap(image);
}

A few notes:

  • OpenCV 2 does not often work in RGB unless you make it. It is typically the reverse, BGR. Unless you have a specific need I see no reason not to do the conversion on-the-fly as above.
  • This sample assumes everything is the same width, height, color depth, ect, so watch out for that. Allegro, in particular, may slow to a crawl if you do not watch your conversions.
  • I am very not happy with the performance of this so it does need some work in that respect. It does, however, work very well otherwise. My goal is to get my Atom-based netbook running this smoothly. The Raspberry Pi may be a pipe dream but I am going to try.
  • This was tested in Linux with hardware I know what to expect out of. If there is any chance your webcam/video/whatever may return something other than a 24-bit (uint8, uint8, uint8) BGR color space you will need to account for that. Both OpenCV and Allegro have a number of functions/macros for that kind of thing.

This is mostly for my own notes but I figured someone else might also be interested. None of this is meant to be complete but, if you are struggling like I was, this should be all you need to pass that hurdle. Give a man a fish… alright, back to my cold, week-old “chinese” food and root beer.

Update 2012.11.28
After some more experimentation (and a nudge in the right direction from Peter Wang) I have tweaked the guts and it now runs much, much faster:

video >> frame;
if ( !frame.empty() ) {
	ALLEGRO_LOCKED_REGION *region = al_lock_bitmap(image, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_WRITEONLY);
	for ( int y = 0; y < [height]; y++ ) {
		for ( int x = 0; x < [width]; x++ ) {
			uint32_t *ptr32 = (uint32_t *)region->data + x + y * (region->pitch / 4);
			*ptr32 = (frame.data[y * webcam_width * 3 + x * 3 + 0] << 16) | (frame.data[y * webcam_width * 3 + x * 3 + 1] << 8) | (frame.data[y * webcam_width * 3 + x * 3 + 2] << 0);
		}
	}
	al_unlock_bitmap(image);
}

Compile Allegro 5.0.x on Linux Mint and Ubuntu

Compile Allegro 5.0.x on Linux Mint and Ubuntu

As a sister article to my Cross Compile Allegro 5 Programs in Linux for Windows post, here are the steps I took to get Allegro 5 installed on Linux Mint 13, Linux Mint 14, and Ubuntu 12.10:

  1. Download and extract the latest .tar.gz-compressed source.
  2. Install the required packages: sudo apt-get install -y cmake g++ freeglut3-dev libxcursor-dev libpng12-dev libjpeg-dev libfreetype6-dev libgtk2.0-dev libasound2-dev libpulse-dev libopenal-dev libflac-dev libdumb1-dev libvorbis-dev libphysfs-dev
    • [Note] Would be a good idea to do a sudo apt-get update first.
  3. Create a workspace: mkdir "build" && cd "build/"
  4. Create make files: cmake "../"
    • [Note] By default cmake will want to configure make for a release shared build. If you want a debug build you will need -DCMAKE_BUILD_TYPE=Debug or -DCMAKE_BUILD_TYPE=Profile for a profiling build.
  5. Compile: make
    • [Optional] By default make will not eat up all the processing power it can. Add -j# to change this behavior, where # is the number of job you would like to have running in parallel. If you machine is more or less idle the number of processors available should not hurt anything. If you are using your machine you might want to some half that number instead.
  6. Install to respective paths: sudo make install && sudo ldconfig
    • [Optional] Recommended if you are unsure as to why this step is optional.

If you want to compile an Allegro 5 C++ application– assuming you completed all the steps above and have g++ installed– you can run g++ [source file(s)] -o [output] `pkg-config --libs allegro-5.0`. There are, of course, many more Allegro 5 add-ons (check out pkg-config --list-all | grep allegro) but I will leave using those up to you to discover on your own.

As of this writing Allegro 5 v5.0.8 was the latest version.

Update 2012.11.28
Seems I already had some things installed from some other projects so I did not notice some missing dependencies. Thanks to weapon_S and sorry about that.

Cross Compile Allegro 5 Programs in Linux for Windows

Cross Compile Allegro 5 Programs in Linux for Windows

The Allegro game programming library has released v5 of their popular library and with it comes a whole mess of great changes. Thing is, since most of the applications you make with it are going to be games, your main audience lives in Windows. Since I am really upset with Microsofts offerings in this area I needed a way to capture this audience without having to drive myself insane.

What follows is how I am making Windows executables in Linux using Allegro. Please note that I live in Ubuntu (currently 10.10, Maverick Meerkat). You may have to make some slight changes to fit your distro but that should not be a big deal. These instructions assume a clean installation where no other copy of Allegro has been installed (not sure if that would be a problem or not as I have not tested).

  1. Install the required programs:
    sudo apt-get install cmake mingw32
  2. Retrieve and uncompress DirectX:
    Download and copy the DirectX headers and libraries to /usr/i586-mingw32msvc/. Note the file structure within the archive should compare to the mentioned directory. When prompted to overwrite any files do so but make sure you have a backup first in case something explodes.
  3. Retrieve and uncompress Allegro 5:
    Download allegro-5.x.x.tar.gz from their site. Uncompress some place easy to get to. I used my desktop as we can delete this when done.
  4. Compile from source:
    In a terminal type
    cd [path to uncompressed archive] && mkdir build && cd build && cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-mingw.cmake .. && make && sudo make install
    This may take a little while depending on your hardware.

You should now have a functioning cross compiler setup for Allegro 5. Just replace gcc with i586-mingw32msvc-gcc or g++ with i586-mingw32msvc-g++ (for example, I compiled my first test with i586-mingw32msvc-g++ alleg.cpp -lallegro.dll -lallegro_image.dll -lallegro_font.dll -o alleg.exe). The DLLs you will need are in /usr/i586-mingw32msvc/bin/. You may now delete all of our working files on your desktop (or wherever you put them).

There are still one or two things I need to figure out. For one, dynamically linked programs are peachy on Linux; I am comfortable in my assumption that most people using Linux either already expect this or are willing to learn. Windows, not so much. I want to statically link for that platform but I have yet to experiment with that. Another thing is the fact that my current method has Windows opening up a console window in addition to the “main” window. I am sure this is also very simple but have not yet played with it.

RoboCode Tournament

RoboCode Tournament

I have become very interested in playing with RoboCode as of late. Wikipedia sums it up pretty nicley:

Competitors write software that controls a miniature tank that fights other identically-built (but differently programmed) tanks in a playing field. Robots can move, shoot at each other, scan for each other, and hit the walls (or other robots) if they aren’t careful. Though the idea of this “game” may seem simple, the actual strategy needed to win is not. Good robots can have thousands of lines in their code dedicated to strategy. Some of the more successful robots use techniques such as statistical analysis or attempts at neural networks in their designs.

I do go on with my rants about Java however I have gone as far as proposing an in-house tournament between friends. I have even drawn up game types and rules for this tournament. This could prove to be a great introduction to programming for them and a lot of fun for everyone.

Also I get to crush their robots with great prejudice in robo-combat.

Robot Traverses Maze

Robot Traverses Maze

At the Singapore Robotic Games where “automation is a key factor towards advancement… to a technologically sophisticated country” some people have built a maze for robots to run through.

This is very similar to something I had done in high school except my maze and robots were virtual. With the introduction of the LEGO Mindstorms things that were the domain of nerds in academic labs before are now accessible to a wider audience. This audience includes people of a younger age than was commonly seen before. I often wonder what technology that I drooled over a year ago will soon be inexpensive enough for me to buy and screw around with.

[youtube]bproY7G2t4o[/youtube]
2009 Singapore Robotic Games MicroMouse Robot Competition

npak

npak

It is odd I talk nuts and bolts here but here we go.

I have been playing with the idea of a backup file format that can store multiple files from multiple back ups. The biggest up side of this is space; Why backup redundant data? Create some low-overhead method of detecting changes, do the work once, and store it. The biggest down side is that there is no fantastic way to do this without either a ton of disk reads/writes or tons of memory. Since most users do not have 4GBs of RAM but do have a lot of free disk space the answer seems obvious. Of course disk writes are much, much slower than primary storage but there is no other portable solution for the average PC.

Here is the pre-pre-release file format I am currently kicking around:

================================

= Terminology =

================================

Page:

Collection of files within a pack-style format.

Chunk:

Files are broken down to chunks of N size and hashed. These hashes are stored and used to determine if a chunk of a file has changed.

================================

= File Format =

================================

String: "npak"

Integer: [Major Version]

Integer: [Minor Version]

Integer: [Chunk Size]

Integer: [Number of Pages]

foreach ( page ) {

Integer: [Page Size]

[Page]

}

String: "end npak"

================================

= Page =

================================

String: "start page"

foreach ( file ) {

Integer: [File Name Length]

String: [File Name]

Integer: [Date Created]

Integer: [Date Modified]

Integer: [Date Accessed]

Integer: [File Location]

Integer: [File Length]

foreach ( chunk ) {

Integer: [Chunk Hash]

}

}

[File Data]

String: "end page"

Simple Tanks

Simple Tanks

Ah, Simple Tanks. My pet project I always get so excited about and never finish (or never really start). Every time I hit a tiny snag I have not encounter before I stop. This time it is uniquely identifying objects over the network with each player. Big problem no one has ever tackled before? Hardly. I also came across a problem I have already solved– at least in theory which is good enough for me right now– and I have yet to implement that. On top of that it would have far reaching applications for me if I just sat down and did some of these networking things.

Alas.