I've just installed CrunchBang in VirtualBox two days ago, but the resolution was limited so it cannot fit my monitor properly. After some trials (including some struggles when installing the so-called Guest Additions), I successfully changed the resolution to my need.
But there's some more work to do to make the change permanently. We need to add the following lines (from my own setting) in ``~/.config/openbox/autostart'':
Actually this confused me and I'm not sure about every details. Here I just write down what I've done for your reference.
The first thing I did was to insert the VBoxGuestAdditions.iso image via the GUI (I've selected the iso file before, so it appeared in the list automatically):
Then click the ``Insert Guest Additions CD image...'' or use the following command to mount the image:
mount /dev/sr0 /media/cdrom
Now we can find the ``VBoxLinuxAdditions.run'' script and run it:
In the previous post [1] I've tried the GrabCut function of OpenCV, when I noticed it was time consuming but didn't try to check the exact processing time. But I was still wondering ``how slow'' did GrabCut could be. So, I started to add the clock() function to see the result [2].
Later, I though of that the processing time was greatly affected by the image size, so I searched for functions which could reduce the images for speeding up GrabCut. What I found were cv::pyrDown() and cv::pyrUp() and they've been implemented in my test code (listed below).
#include "opencv2/opencv.hpp"
#include <iostream>
#include <time.h>
using namespace std;
const bool DOWN_SAMPLED = true;
const unsigned int BORDER = 1;
const unsigned int BORDER2 = BORDER + BORDER;
int main( )
{
clock_t tStart_all = clock();
// Open another image
cv::Mat image;
image = cv::imread("sunflower02.jpg");
if(! image.data ) // Check for invalid input
{
cout << "Could not open or find the image" << std::endl ;
return -1;
}
cv::Mat result; // segmentation result (4 possible values)
cv::Mat bgModel,fgModel; // the models (internally used)
if(DOWN_SAMPLED){
// downsample the image
cv::Mat downsampled;
cv::pyrDown(image, downsampled, cv::Size(image.cols/2, image.rows/2));
cv::Rect rectangle(BORDER,BORDER,downsampled.cols-BORDER2,downsampled.rows-BORDER2);
clock_t tStart = clock();
// GrabCut segmentation
cv::grabCut(downsampled, // input image
result, // segmentation result
rectangle,// rectangle containing foreground
bgModel,fgModel, // models
1, // number of iterations
cv::GC_INIT_WITH_RECT); // use rectangle
printf("Time taken by GrabCut with downsampled image: %f s\n", (clock() - tStart)/(double)CLOCKS_PER_SEC);
// Get the pixels marked as likely foreground
cv::compare(result,cv::GC_PR_FGD,result,cv::CMP_EQ);
// upsample the resulting mask
cv::Mat resultUp;
cv::pyrUp(result, resultUp, cv::Size(result.cols*2, result.rows*2));
// Generate output image
cv::Mat foreground(image.size(),CV_8UC3,cv::Scalar(255,255,255));
image.copyTo(foreground,resultUp); // bg pixels not copied
// display original image
cv::namedWindow("Image");
cv::imshow("Image",image);
// display downsampled image
cv::rectangle(downsampled, rectangle, cv::Scalar(255,255,255),1);
cv::namedWindow("Downsampled Image");
cv::imshow("Downsampled Image",downsampled);
// display downsampled mask
cv::namedWindow("Downsampled Mask");
cv::imshow("Downsampled Mask",result);
// display final mask
cv::namedWindow("Final Mask");
cv::imshow("Final Mask",resultUp);
// display result
cv::namedWindow("Segmented Image");
cv::imshow("Segmented Image",foreground);
}
else {
cv::Rect rectangle(BORDER,BORDER,image.cols-BORDER2,image.rows-BORDER2);
clock_t tStart = clock();
// GrabCut segmentation
cv::grabCut(image, // input image
result, // segmentation result
rectangle,// rectangle containing foreground
bgModel,fgModel, // models
1, // number of iterations
cv::GC_INIT_WITH_RECT); // use rectangle
printf("Time taken by GrabCut with original image: %f s\n", (clock() - tStart)/(double)CLOCKS_PER_SEC);
// Get the pixels marked as likely foreground
cv::compare(result,cv::GC_PR_FGD,result,cv::CMP_EQ);
// Generate output image
cv::Mat foreground(image.size(),CV_8UC3,cv::Scalar(255,255,255));
image.copyTo(foreground,result); // bg pixels not copied
// display original image
cv::rectangle(image, rectangle, cv::Scalar(255,255,255),1);
cv::namedWindow("Image");
cv::imshow("Image",image);
// display result
cv::namedWindow("Segmented Image");
cv::imshow("Segmented Image",foreground);
}
printf("Total processing time: %f s\n", (clock() - tStart_all)/(double)CLOCKS_PER_SEC);
cv::waitKey();
return 0;
}
The key idea was to downsample the image for GrabCut and then upsample the result (I thought it was a mask) to the original size. The result showed a remarkable speeding up in both the debug and the release mode.
Here are the output images with the downsampling strategy:
Fig 1. Original image
Fig 2. Downsampled image
Fig 3. Mask obtained by using GrabCut
Fig 4. Upsampled mask
Fig 5. Final result
Here is the result without the downsampling strategy:
Fig 6. GrabCut result without downsampling
Comparing Figure 5 and 6, we can easily notice the differences between the segmented results. When applying the downsampling strategy, some image details were lost and the mask would be different and had rougher edges as well.
Although the downsampling strategy has the drawback of losing image details, the benefit of reducing processing time was significant. The following table lists the processing time obtained by using above code with and without the downsampling strategy.
As mentioned in the previous post, in which I tried the GrabCut by using the OpenCV's library. Because I didn't have libs and dlls for debug mode, so I tried to use CMake to build them for my own usage.
First I went to OpenCV website to download the latest stable version 2.4.6. The source code for Windows were packed in a exe file. Don't worry about it, just download it and click it and the 7zip will extract the whole source package for you. In my case, the extracted folder was named ``opencv''.
Then I lauched CMake GUI, chose the location where the extracted folder was located, and chose the build directory for the building files.
Click the ``Configure'' button and if everything is okay then the ``Generate'' button. In my case, I'd chosen the generator as ``Visual Studio 2005'' (at a certain step I didn't rememberd0, so the generating result contained an OpenCV.sln in the build folder.
The final step was just click the OpenCV.sln to launch the Visual Studio and then Build the project for Debug and Release mode. The products were located in the build/bin and build/lib directories.
I was considering using GrabCut to cut out the target in one of my working project. After testing it using Python, I thought it's necessary to try it in C++ code. Therefore I started to find some example code and picked one for my test [1].
Here is my test code, the sample photo, and the result:
#include "opencv2/opencv.hpp"
#include <iostream>
using namespace cv;
using namespace std;
int main( )
{
// Open another image
Mat image;
image = cv::imread("sunflower02.jpg");
if(! image.data ) // Check for invalid input
{
cout << "Could not open or find the image" << std::endl ;
return -1;
}
// define bounding rectangle
int border = 20;
int border2 = border + border;
cv::Rect rectangle(border,border,image.cols-border2,image.rows-border2);
cv::Mat result; // segmentation result (4 possible values)
cv::Mat bgModel,fgModel; // the models (internally used)
// GrabCut segmentation
cv::grabCut(image, // input image
result, // segmentation result
rectangle,// rectangle containing foreground
bgModel,fgModel, // models
1, // number of iterations
cv::GC_INIT_WITH_RECT); // use rectangle
// Get the pixels marked as likely foreground
cv::compare(result,cv::GC_PR_FGD,result,cv::CMP_EQ);
// Generate output image
cv::Mat foreground(image.size(),CV_8UC3,cv::Scalar(255,255,255));
image.copyTo(foreground,result); // bg pixels not copied
// draw rectangle on original image
cv::rectangle(image, rectangle, cv::Scalar(255,255,255),1);
cv::namedWindow("Image");
cv::imshow("Image",image);
// display result
cv::namedWindow("Segmented Image");
cv::imshow("Segmented Image",foreground);
waitKey();
return 0;
}
The sample photo used in the test
The result of applying GrabCut
During the test, I encountered an old problem to me, which had been some odd runtime bugs for the debug mode when using OpenCV. The solution might be NOT to mix up the debug and release libraries [2].
Oh, by the way, the processing time of the GrabCut was too long (about 2 seconds in the test case), and I thought it's not feasible for realtime applications. Orz
Yesterday I searched the problem on Google and found nothing useful (according to my skill level, I might overlooked something that could be hints), so I decided to ask in the G+ Python community [1].
Then I noticed a magic word ``0xFF'' in the new downloaded sample code. Using the hint, I finally found the bug report about cv2.waitKey() and came up with a tiny test code:
import cv2
import numpy as np
cv2.namedWindow('test')
while True:
#key = cv2.waitKey(33) #this won't work
#key = 0xFF & cv2.waitKey(33) #this is ok
key = np.int16(cv2.waitKey(33)) #this is ok [2]
if key == 27:
break
else:
print key, hex(key), key % 256
cv2.destroyAllWindows()
I was trying to evaluate the feasibility of a project, and Python of course was my first choice. During the build-up of the developing environment, however, I was frustrated due to the installation of scikit-learn package.
Quick tip: download the latest stable version (0.14a1) of scikit-learn and play with the sample code given in the source package.
Installation by pip (failed)
The first frustration might be caused by my stupidity.
I googled for the solution again and again, and found all the answers pointed to ``multiple versions of Python installed in the system.'' But I have only Python 2.7 in my Ubuntu!
What I had done was uninstall the scikit-learn and reinstall. Also I tried to install it from the source, but nothing changed.
Then I thought of something and tried to find some sample code on the scikit-learn page. It turned out that the module should be sklearn instead of scikits.learn... Orz
So what I had found was a sample code using old module names.
Using version 0.13.1 (failed)
I am not sure whether this is a bug. I could not run the example code (fa_recognition.py) located in the source package of version 0.13.1. When my scikit-learn modules were also the version 0.13.1. The error message was:
ImportError: cannot import name column_or_1d
and I found ``import sklearn.datasets'' would trigger this error.
I also tried to follow the traceback message given by the interpreter but only knew it was due to an importing of label.py. My skill on debugging couldn't bring me further.
Verion 0.14a1 (Succeeded)
Okay, I'd run out my approaches... I almost gave up, but then I thought of the possibility of using the latest version to solve the problem. So I downloaded the source of version 0.14a1 and installed it. Finally, I got the sample code run with expected outputs.
Face recognition example test
If you have downloaded the source package, you can find the example in the path of: YOUR_FOLDER/scikit-learn-0.14a1/examples/applications/face_recognition.py.
Frankly, I have no idea about the output yet, but I would like to post the text output of running face_recognition.py with the figures of result.
Text output
===================================================
Faces recognition example using eigenfaces and SVMs
===================================================
The dataset used in this example is a preprocessed excerpt of the
"Labeled Faces in the Wild", aka LFW_:
http://vis-www.cs.umass.edu/lfw/lfw-funneled.tgz (233MB)
.. _LFW: http://vis-www.cs.umass.edu/lfw/
Expected results for the top 5 most represented people in the dataset::
precision recall f1-score support
Gerhard_Schroeder 0.91 0.75 0.82 28
Donald_Rumsfeld 0.84 0.82 0.83 33
Tony_Blair 0.65 0.82 0.73 34
Colin_Powell 0.78 0.88 0.83 58
George_W_Bush 0.93 0.86 0.90 129
avg / total 0.86 0.84 0.85 282
2013-07-31 08:04:43,243 Downloading LFW metadata: http://vis-www.cs.umass.edu/lfw/pairsDevTrain.txt
2013-07-31 08:04:46,028 Downloading LFW metadata: http://vis-www.cs.umass.edu/lfw/pairsDevTest.txt
2013-07-31 08:04:46,740 Downloading LFW metadata: http://vis-www.cs.umass.edu/lfw/pairs.txt
2013-07-31 08:04:48,140 Downloading LFW data (~200MB): http://vis-www.cs.umass.edu/lfw/lfw-funneled.tgz
2013-07-31 08:11:24,620 Decompressing the data archive to /home/thk/scikit_learn_data/lfw_home/lfw_funneled
2013-07-31 08:11:33,822 Loading LFW people faces from /home/thk/scikit_learn_data/lfw_home
2013-07-31 08:11:33,981 Loading face #00001 / 01288
2013-07-31 08:11:36,218 Loading face #01001 / 01288
Total dataset size:
n_samples: 1288
n_features: 1850
n_classes: 7
Extracting the top 150 eigenfaces from 966 faces
done in 0.806s
Projecting the input data on the eigenfaces orthonormal basis
done in 0.065s
Fitting the classifier to the training set
done in 16.244s
Best estimator found by grid search:
SVC(C=1000.0, cache_size=200, class_weight=auto, coef0=0.0, degree=3,
gamma=0.001, kernel=rbf, max_iter=-1, probability=False,
random_state=None, shrinking=True, tol=0.001, verbose=False)
Predicting people's names on the test set
done in 0.049s
precision recall f1-score support
Ariel Sharon 0.67 0.78 0.72 18
Colin Powell 0.77 0.80 0.78 61
Donald Rumsfeld 0.71 0.76 0.73 29
George W Bush 0.90 0.89 0.89 134
Gerhard Schroeder 0.71 0.63 0.67 27
Hugo Chavez 0.93 0.58 0.72 24
Tony Blair 0.69 0.83 0.75 29
avg / total 0.81 0.80 0.80 322
[[ 14 2 1 1 0 0 0]
[ 3 49 1 3 0 1 4]
[ 1 3 22 2 0 0 1]
[ 2 6 4 119 1 0 2]
[ 1 1 1 4 17 0 3]
[ 0 3 1 0 5 14 1]
[ 0 0 1 3 1 0 24]]
(This was an old article kept in draft state for about four months)
In previous post I installed the OpenNI SDK and tested some of its samples [1]. I am trying to study something from the sample code and what I've chosen now is the NiSimpleViewer example (which can be found in openni/Samples/NiSimpleViewer).
To avoid messing up the original sample code, I copied the whole directory of NiSimpleViewer and renamed it to mySimpleViewer.
The first work was to compile the source code. Of course the samples included makefiles but they were used for more general and more complicated cases. What I needed was just a simple and self-contained makefile. My first attempt was to simplify the makefile, but unfortunately it's too complicate for me to understand or even to modify it. So I wrote a simple one as the follows (I knew it's unnecessary to do so for such a simple case, but I just wanted to do a bit of exercise on writing makefiles.) :
After running mySimpleViewer, the program complained that the file SamplesConfig.xml cannot be found. I checked the source code as well as the files in related directories and found the path should be changed from
../../Config/SamplesConfig.xml
to
../Config/SamplesConfig.xml
In fact the relative path for the source code to find the xml file is ``../Config'' but not ``../../Config''. This was because the original Makefile putted the binaries in openni/Samples/Bin/Release/ which was one more directory deeper than my test example (thanks to my colleague's reminder).
Also, I modified some #define macros to const type. Based on my knowledge, this would be more ``c++ style''.
const XnChar* SAMPLE_XML_PATH = "../Config/SamplesConfig.xml";
const int GL_WIN_SIZE_X = 1280;
const int GL_WIN_SIZE_Y = 1024;
const unsigned int DISPLAY_MODE_OVERLAY = 1;
const unsigned int DISPLAY_MODE_DEPTH = 2;
const unsigned int DISPLAY_MODE_IMAGE = 3;
const unsigned int DEFAULT_DISPLAY_MODE = DISPLAY_MODE_DEPTH;
I have installed and used Linux Mint (Maya) on my Toshiba Satellite for several months. The network setting has always troubled and annoyed me, especially the wireless one.
I had encountered three problems:
If the cable doesn't connect to the laptop or the network is not working, the system always wait for a long time with the messages read:
``Waiting for network configuration...''
``Waiting up to 60 more seconds for network configuration...''
When the network is interrupted, it won't recover automatically.So every time I close the laptop lid to sleep the system and open it to resume it, I have to open the terminal and type ``sudo pon dsl-provider'' to get the network connection back.
I couldn't connect to my wireless network at home, and found nowhere to get the settings done. My wireless network has been set as hidden, and I have added it in the Network Connections. But when I tried to connect it, the icon always showed the processing state and the connection was never done.
Today I got all these problems solved and I am happy now.
Here are the solutions I found and tested successfully:
Edit the file: /etc/init/failsafe.conf
Find the lines with ``sleep'' and comment out the two which related to the system messages just mentioned above.
Reinstall network-manager by
sudo apt-get --reinstall install network-manager
and use the following command to start the manager:
sudo /etc/init.d/network-manager restart
Edit the file: /etc/NetworkManager/NetworkManager.conf
change ``managed=false'' to ``managed=true''
restart the network manager by
sudo /etc/init.d/network-manager restart
After doing these, the available wireless network will show up. My hidden wireless network still couldn't be connected so I tried to click its icon and a window popped out for me to enter the password. I inputed the password and everything went as expected as shown in the figure:
I had used wmii for several months, and almost forgot it till today when my Ubuntu 12.04 stuck. I launched top and found the compiz consumed most of the resource of my PC. Of course I didn't find out the cause (due to my time and my skill level) and finally restart the system in command line mode.
So I recalled wmii the wonderful and lightweight window manager.
But I also recalled some reasons which prevented me using wmii as my main window manager:
I didn't know how to make wmii show the system panel (that was the gnome panel) which keeps something like volume controls and daemon icons of ibus and Dropbox, etc.
I have had two monitors and didn't know how to make wmii work with dual-monitor setting
I did some quick search and found an interesting article written by Tanguy: Tiling window managers.
The article listed three tilting window managers among which I've only used wmii. I heard of awesome but haven’t try it yet. After reading Tanguy's introduction, I decided to try i3.
I also did some more search about the system panel and finally got what I want. I listed some setting in my i3 configuration file (~/.i3/config):
where the DVI-I-1 and DVI-I-2 are my monitors detected by using the command xrandr.
Here is my working monitors with i3 as the window manager:
Using i3 window manager with dual monitors.
Close-up of the Unity panel.
I am not sure whether I got the dual-monitor setting right. In my case, the monitors show two different workspace but not a single workspace with extension monitor.
As mentioned in the previous post [1], I need to replace dots to other tokens in the filenames of a bunch of eps figures. The following script was used to do the work [2]:
#!/bin/sh
for f in $(find . -name "*.eps" -type f)
do
echo "found: "$f
# option -n is useful to preview the renamed results:
rename -v 's/(\d+)\.(\d+)\.(\d+)/$1-$2-$3/' $f
done
In this case, I learned how to keep some parts of the old string and to replace other parts. The key concept was to use parentheses to group the parts we want to keep and then use $n to indicate the nth group in substitution expression. Use ``91.1.8.eps'' as the example:
\d stands for digits
\d+ means at least ONE digit
(\d+) hold the parts which are respectively 91, 1, and 8 in this example
$1 corresponds to the first group which is 91
$2 corresponds to the second group which is 1
$3 corresponds to the third group which is 8
Therefore, the dots between the digits will be replaced by dashes.
Substitution in Vim
After renaming all the eps files, I had another more complicated problem. All the corresponding filename strings resided in the tex files also had to be changed! At the beginning I edited one of the tex file in Vim and played with the substitution command in it. The final command I used was [3][4]:
:%s/\(\d*\)\.\(\d*\)\.\(\d*\)/\1-\2-\3/gc
Note that there are some minor differences when writing the expressions. Some of the modifications, e.g. the escaping backslash, were due to the difference between BRE and ERE [5].
Find and Replace in multiple files
Although I could do the find and replace works in Vim, it was not a good idea when there were maybe hundreds of such files. To write a bash script was my first thought and with information found on the internet [6][7][8] I got a usable script as the follows:
#!/bin/sh
for f in $(find . -name "*.tex" -type f)
do
echo "found: "$f
perl -p -i -e 's/(\d+)\.(\d+)\.(\d+)/$1-$2-$3/' $f
done
My office PC has been linked to two printers via network (intranet I think...) and had been worked fine until recently. Although I have installed and used Ubuntu 12.04 for a while but have not printed files often. Several weeks ago I tried to print some documents but the printers just gave me strange error messages and stopped working. Today I tried to print something again and had the same problem with the printers. This time I decided to make it work.
At the beginning I had only vague keywords and got no useful searching results in return. I tried to launch LibreOffice Writer to create a simple test file and it was printed successfully, but after saved as PDF the printing was failed. Then I noticed that the documents which had failed in printing were also all PDF files. So the problem could be the file type.
I used PDF as one of the searching keywords and found some bug reports of Ubuntu. I followed some suggestions in one of the threads [1] and got little success.
I had a set of tex files which included many eps figures and were compiled successfully by using the latex+dvips+ps2pdf commands. But due to some Unicode issues I've shifted to XeTeX for at least several months [1]. A strange problem, however, emerged when I was invoking xelatex to compile the same set of tex files. The error message was:
! Unable to load picture or PDF file './EPS_FILE_DIR/91.1.8.eps'.
That's strange because I remembered that I have compiled other tex files with eps figures with xelatex flawlessly. I found the successfully compiled files to make sure it still could be compiled in my machine. It did. So the problem might be caused by the 91.1.8.eps itself. Suddenly it occurred to me that maybe the dots confused the xelatex command, so I changed its filename to 91_1_8.eps and solved the problem.
Although the problem has been solved, I still have no idea about why the dots could cause such a problem. I also tested with a 91.1.8.jpg file and to my surprise it passed the compilation without the error message.
I don't know whether other files (such as png, bmp, pdf, ...) also have similar problems, but I decided not to use dots to name my files anymore.
In the previous post I said using Vistalizator to change the display language in Win7 is easily. It was easy indeed, but there were some problems and I have only solved one of it.
After graduating from the university and leaving the lab, my work has been nothing to do with aerial vehicles. I have had no time to keep the RC flying hobby and gradually my interesting (partly due to my work) has been shifted to programming for vision applications.
Maybe one day I will have time to fly RC aerial vehicles again, but for now I am focusing on the topics of image processing and programming and hoping I could get more experiences in the future. So I changed the blog title, which is simple and contains no non-ascii characters, and with the tiny change I could help myself to focus on techniques I want to develop.
In the previous post I tried to make the Kinect (for Windows) work in my Win7 with x86 driver. Actually my first attempt was to try to make the Kinect work in my Ubuntu 12.04 but failed, so I switched back to Win7 to make sure the Kinect is workable.
Several days ago I wanted to test the Kinect in my Ubuntu 12.04, and of course I googled and got OpenKinect. I followed the installation procedure but got no luck and before proceeding on I decided to make sure the Kinect is okay (and therefore `the previous post' about the test in Win7).
My installation steps were slightly different from that described in igorbarbosa's tutorial. I believe it is due to the version changes of avin2's SensorKinect driver.
Now I am sharing my installation and hope it might be useful to you.
Warning: Do NOT use Vistalizator to change your display language. I have encountered something annoying and decided to restore my system. I will post some screenshots of the applications in my Win7 which were affected by Vistalizator.
For the problems cause by Vistalizator in my Win7, see this post.
In the previous posts [1][2] I tried to rebuild a VS project using Kinect given by my colleague and encountered some problems. Because my Win7 is the x64 version but the project had been built for x86 (Win32) platform, the rebuilding work in my Win7 machine cost me and my colleague almost a whole working day (without my colleague's help, I may give up the rebuilding).
Although I changed the project configuration to x64 [2], there were still problems with other libraries, for instance, OpenCV, built along with the project for x86 platform. When I was wondering the next step, my colleague suggested me to try the x86 driver of Kinect and if it works, just keep sticking on the Win32 setting of the project configuration.
Hmm, it seemed I had taken a long route and headed back to the origin... XD
Okay, the happy news is the x86 driver really worked in the x64 Win7, and here is a working log of the test.
I was rebuilding a Win32 project in my x64 Win7 PC. The online sources [1][2] told me just to change the active project configuration from Win32 to x64, but my VS2005 has no x64 option. Then it occurred to me that maybe I didn't install something related to x64 modules when installing the VS2005, so I checked it by using the installation package.
I was rebuilding a project given by my colleague and encountered strange error message:
c1xx : fatal error C1083: Cannot open source file: 'WIN32': No such file or directory
This error was caused by an empty path variable [1] $(OPEN_NI_INCLUDE) which (I guess) indicates the directory containing the installed OpenNI SDK. It was empty because I forgot to restart Visual Studio after install the SDK... :-p
So the solution is simple: restart Visual Studio and the path variable will be set.
---
Edit:
After solving the previous problem, I got another similar problem which related to the Linker path.
I used the set command [2] in cmd of Windows to the list environment variables about OpenNI:
Then I changed $(OPEN_NI_LIB) to $(OPEN_NI_LIB64) and the new error message said the file OpenNI.lib cannot be found, and the reason was it should be OpenNI64.lib in my system. The right place to change the library file name is in the following path: