Monday, April 3, 2023

How to create a Arm64 Ubuntu virtual machine using Virt-Manager

I wanted to run Ubuntu on an Arm64/Aarch64 virtual machine on a host Intel Linux computer for the longest time for compiling binaries for Raspberry Pis and other SBC boards. I finally figured out how to do it with virt-manager, and it is quite simple as clicking and selecting options on the virt-manager graphical user interface. The instructions below show how it is done.

Download and install prerequisites

  1. In Ubuntu, open up a Terminal and enter the following commands to install the prerequisite software.

    $ sudo apt install qemu-kvm \
    libvirt-daemon-system \
    libvirt-clients \
    bridge-utils \
    virt-manager \
    qemu-system-arm \
    qemu-efi-aarch64 \

  2. Open up an Internet browser. Download an Ubuntu Arm64 image to install. For example:

 Create the virtual machine

  1. In Ubuntu, click the Virtual Machine Manager icon.

    The Virtual Machine Manager application appears.

  2. Select File | Create New Virtual Machine.

    The New VM dialog box pops up.

  3. Choose Local install media (ISO image or CDROM).

  4. In the Architecture options, choose aarch64 architecture. Click Forward.

    Step 2 of 5 pages appears.

  5. In the Choose ISO or CDROM install media field, choose the iso image downloaded previously.

  6. Click Forward. If necessary, change the memory size and the number of CPUs.

    Step 3 of 5 pages appear.

  7. Click Forward. If necessary, change the disk image size to a suitable size.

    Step 4 of 5 appears.

  8. Click Forward.

    Step 5 of 5 appears.

  9. Optional. In the Name field, type in a desired name.

  10. Toggle On the Customize configuration before install field.

  11. Click Finish.

    The 'vm name' on QEMU/KVM dialog box appears.

  12. In the Hypervisor Details group, change the Firmware to UEFI aarch64.

  13. Click Apply. Then click the Begin Installation button and follow the prompts to complete the installation.

    The installation begins...

Monday, March 27, 2023

Convert a sequence of JPG images into a MP4 video using FFMPEG

If you have a sequence of images like the screen shot below, it is quite straightforward to use ffmpeg to concatenate them into a single video file. 

Obviously, you need to specify the image file name and sequence pattern, the frame rate to show each image as shown in the example ffmpeg command below.

$ ffmpeg -hide_banner \
-f image2 \
-framerate 1 \
-start_number 1 \
-i %02d.jpeg \
-vcodec mpeg4  \

where -f specifies the input format as image,

-framerate specifies the rate in Hz at which to display each image frame,

-start_number specifies the starting number of the image frame sequence,

-i specifies the file name and sequence pattern, e.g. %02d means a pattern of 2 digits with a prefix character '0' for single digit numbers,

-vcodec tells ffmpeg to output mpeg4 format.

 Running the command will display the following output and generate the output video file output.mp4.

Monday, January 30, 2023

Fixing a kernel panic error when installing Ubuntu 20.04 in VirtualBox

I was trying to create an Ubuntu 20.04 virtual machine using Oracle VirtualBox but I kept encountering this error with the message "...end kernel panic - not syncing: Attempted to kill the idle task!..." The screenshot below shows the error in VirtualBox.

Eventually, I found out the error was caused by inadequate alllocated CPU resources in VirtualBox. By default, the number of CPU allocated for the VM is 1, as shown in the screen shot below.

Simply increasing the number of CPU to at least 2 helped to solve the kernel panic error in this case.

Monday, December 12, 2022

How to read an array from a ROS1 launch file into a C++ vector variable

I was having problems reading an array of doubles in a ROS launch file into a vector variable in a C++ ROS1 program node. After some digging around, I found I was doing it the wrong way; instead of using the <param> tag in the ROS launch file, I should be using the <rosparam> tag. 

The example ROS launch file listing shows the correct way to enter an array, e.g. [0.01, 0.1, 0.2] with the <rosparam> tag:

?xml version="1.0" encoding="UTF-8"?>
  <node pkg="learning_tutorial" type="my_node" name="my_node">
        <param name="my_string_param" value="hello" />
        <rosparam param="my_array_param">[0.01, 0.1, 0.2]</rosparam>

Then in the ROS C++ code, I could do the following to read the array:

// ...etc...

using namespace ros;
using namespace std;

vector<double> myArrayParam;
NodeHandle nh;

// Read the my_array_param from the launch file into the myArrayParam variable
nh.param<vector<double>> ( "my_array_param", myArrayParam, { 1, 2, 3});

// Just print out the array parameter
ROS_INFO ( "My array: %f, %f, %f", myArrayParam[0], myArrayParam[1], myArrayParam[2]);
// ...etc...

Hope this helps somebody.

Monday, December 5, 2022

Using GIMP to copy an image layer into a channel

In GIMP, it is possible to copy a colored image layer into a single grayscale channel. Here's how to do the job.

Create an empty channel

  1. In GIMP, open up the image file.

  2. Click the Channels tab on the bottom right.

  3. Then click the Create a new channel icon.

    The New Channel dialog box appears.

  4. Optional. In the Channel name field, type in a name, e.g. flats. In the Fill opacity field, slide to 50.0.
  5. Click OK.

    A new channel is created.

Copy and paste the colored image into the channel

  1. Click the Layers tab. Click the image layer, e.g. bored-tiger.jpg to make sure it is active.

  2. In the menu, choose Select | All. Then choose Edit | Copy.

    The layer is copied to the clipboard.

  3. Click the Channels tab. Click the previously created channel, e.g. flats.

  4. In the menu, select Edit | Paste in Place

  5. Then click the Layers tab.

    A Floating Selection (Pasted Layer) is visible in the Layers list.

  6. Click the green Anchor the floating layer icon.

    The pasted layer is added to the active channel.

  7. Optional. Click the Channels tab.

    Note the channel thumbnail has been updated with a grayscale image of the pasted layer.

Monday, November 28, 2022

Using GIMP's color channels to remove blue guide lines from inked line art

Penciled comic book art typically have blue guide lines (and text) as shown in the screen shot below. 

The sketch can be downloaded from this site if you want to practice with it. There are a number of ways to remove the blue lines from the image. I will be using the Color channels panel to remove the guide lines.

The steps:

Remove pixels from the Red and Green channels

  1. In GIMP, open up the image. Click the Channels tab on the bottom right.

  2. Click the Blue channel to deselect it.

  3. In the Tool palette, click the Fill icon.

  4. Toggle on the FG color fill. Make sure the foreground color is black since we want to remove the Red and Green channels data.

  5. Then, click anywhere on the canvas.

    The background becomes blue.

Create the line art in the Red and Green channels

  1.  In the Channels tab, press the mouse right click button on the Blue channel.

    A popup menu appears.

  2. Choose Channel to Selection.

    The blue channel's non-zero pixels are selected.

  3. In the Tool box, click the Fill icon. Toggle on the BG color fill option. (Note: the background color should be white). Then click anywhere in the selection on the canvas.

    The background becomes white.

  4. In the Channels tab, click the Blue channel to select it again.  Then in the menu, choose Select | None to clear the selection.

Use Threshold to clean up the line work

  1. In the menu, select Colors | Threshold.

    The Threshold dialog box appears.

  2.  Drag the black triangle until you are satisfied with the contrast between the line work and the background.

  3. Save your work.

Monday, November 7, 2022

Shell script to batch bulk convert *.flac files to *.mp3

I have many music files in flac format and I wanted to convert them to a more compressed mp3 format with ffmpeg on Ubuntu so I can upload them to a storage limited portable music player. To ease the conversion task, I decided to write this simple shell script to do the job. In brief, the script will do the following:

  • find all the files with the extension .flac in the current directory
  • replace the file name extension .flac with the .mp3 extension
  • create a temporary script that calls the ffmpeg command to convert
  • run the temporary script

The listing of the shell script is shown below.  

# Define the internal field separator as a newline

# Find all the *.flac files in the current directory and perform the conversion
for f in `find . -name "*.flac" `;
	# Use the input flac file name prefix and replace the .flac extension with a .mp3 extension
	f=$(echo $f | cut -c 3-)
	outfile=$(basename $f .flac)
	echo "Convert $f->$outfile..."
	# Form the ffmpeg command to convert the input flac file to mp3
	cmd="ffmpeg -hide_banner -i \"$f\" -ab 320k -map_metadata 0 -id3v2_version 3 \"$outfile\" "
	# Create a temporary shell script for running the conversion
	echo $cmd > /tmp/
	# Run the conversion to mp3
	bash /tmp/
	# Clean up
	rm /tmp/

To use this shell script, you can do the following:

  1. Save the code listing above to a file e.g. in a directory, e.g. /path/to

  2. Open up a Linux Terminal.

  3. In the Terminal, type in the command to change directory to the location of the flac files, e.g. /path/to/music/

    $ cd /path/to/music

  4. At the prompt, type in the command to run the shell script.

    $ bash /path/to/

    The flac files are converted to mp3 files.