Belajar Python Bagian 2: Live Video di OpenCV dan Face Detection

Baiklah, sesuai janji saya, kali ini kita akan mempelajari bagaimana menggunakan live video di OpenCV. Kalau sebelumnya kita menggunakan gambar diam, maka kali ini kita akan menggunakan OpenCV untuk menganalisa video live dari webcam di komputer/laptop. Bisa dibilang, inilah kekuatan OpenCV, di mana ia bisa menganalisa objek bergerak, sebagaimana manusia mampu mengenali objek yang dilihat langsung.

Continue reading →

Belajar Python Bagian 1: Python dan Hello World OpenCV

Sudah beberapa bulan ini saya kesengsem lagi dengan bahasa pemrograman Python. Mungkin karena sedang getol-getolnya baca-baca soal data, statistik dan Machine Learning, jadi ingin belajar Python lagi. Maka dari itu, saya tulis blog ini sebagai catatan perjalanan saya belajar Python lagi.

Continue reading →

Installing OpenCV in Processing for Windows 7

The good thing about having Java OpenCV is we can use Processing along with many of its ease to develop computer vision application. Sure, there does exist additional library that ports Java OpenCV to make development even easier, like this OpenCV for Processing. However, having a vanilla OpenCV will allow you to learn about the inside of this library. I figure that this is a good route, teaching wise. But for something more practical, and faster to develop, please use the aforementioned library. It really is that good.

Now, installing OpenCV in Processing could not be easier. Again, I use pre-build OpenCV 2.4.11. Here are the steps:

1. Download and install Processing
2. Make a new sketch (File – New)
3. Give it a name and save it, even before you type anything
4. Now, in Windows Explorer, go to Processing sketch folder, by default it’s at “My Documents – Processing”
5. Go to where you saved your sketch
6. Now, make a folder named “code” and copy both opencv_2411.jar and opencv_java2411.dll from your opencv_directory/build/java
7. That’s it, now you can use OpenCV inside your Processing sketch.

To test it, let’s copy and paste the code from previous tutorial. It was in Java, so it should be working without any hiccup.

import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Scalar;
import org.opencv.core.Mat;
import org.opencv.highgui.Highgui;

import java.nio.*;
import java.util.List;
import java.awt.*;            
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import javax.swing.*;        

PImage img;
Mat mat;
Mat alpha;

void setup() {
  size(640, 480);
  background(0);
  println(Core.VERSION);
  System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
  noLoop(); //so the code only runs once

void draw() {
  mat = Highgui.imread(dataPath("fifa.png")); //put the file in data directory of your sketch
  Image imgToShow = Mat2BufferedImage(mat);
  displayImage(imgToShow);
}

BufferedImage Mat2BufferedImage(Mat m)
{
  //source: http://answers.opencv.org/question/10344/opencv-java-load-image-to-gui/
  //Fastest code
  //The output can be assigned either to a BufferedImage or to an Image

  int type = BufferedImage.TYPE_BYTE_GRAY;
  if ( m.channels() > 1 ) {
    type = BufferedImage.TYPE_3BYTE_BGR;
  }
  int bufferSize = m.channels()*m.cols()*m.rows();
  byte [] b = new byte[bufferSize];
  m.get(0, 0, b); // get all the pixels
  BufferedImage image = new BufferedImage(m.cols(), m.rows(), type);
  final byte[] targetPixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
  System.arraycopy(b, 0, targetPixels, 0, b.length);  
  return image;
}

void displayImage(Image img2)
{   
  ImageIcon icon=new ImageIcon(img2);
  JFrame frame=new JFrame();
  frame.setLayout(new FlowLayout());        
  frame.setSize(img2.getWidth(null)+50, img2.getHeight(null)+50);     
  JLabel lbl=new JLabel();
  lbl.setIcon(icon);
  frame.add(lbl);
  frame.setVisible(true);
  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

Interestingly, the amazing Bryan Chung gives different and simpler way to do it. He posted it here. Where the image’s pixel data gets read, copied into a buffer array where the colors get arranged properly, before being moved to different array. Hence, the image is being shown properly. I adapted his code here:

import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Scalar;
import org.opencv.core.Mat;
import org.opencv.highgui.Highgui;
 
import java.nio.*;
import java.util.List;
import java.awt.*;            // for ImageIcon type
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import javax.swing.*;           // for ImageIcon type
 
PImage img;
Mat mat;
Mat alpha;
 
void setup() {
  size(640, 480);
  background(0);
  println(Core.VERSION);
  System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
  //noLoop();
}
 
void draw() {
  mat = Highgui.imread(dataPath("fifa.png"));
  Mat out = new Mat(mat.rows(), mat.cols(), CvType.CV_8UC4);
  alpha = new Mat(mat.rows(), mat.cols(), CvType.CV_8UC1, Scalar.all(255));
  byte [] bArray = new byte[mat.rows()*mat.cols()*4];
  img = createImage(mat.cols(), mat.rows(), ARGB);
  ArrayList ch1 = new ArrayList();
  ArrayList ch2 = new ArrayList();
 
  Core.split(mat, ch1);
 
  ch2.add(alpha);
  ch2.add(ch1.get(2));
  ch2.add(ch1.get(1));
  ch2.add(ch1.get(0));
 
  Core.merge(ch2, out);
 
  out.get(0, 0, bArray);
  ByteBuffer.wrap(bArray).asIntBuffer().get(img.pixels);
  img.updatePixels();
  image(img, 0, 0);
  out.release();
}

There you have it. In short, you just need to make a folder named “code inside your Processing sketch folder, and copy both opencv-2411.jar and opencv_java2411.dll there.

Installing Java OpenCV in Eclipse for Windows 7

This one is a bit easier, since the official guide from OpenCV is accurate and I’ve followed it without any trouble. So, you just need to do these:

  1. Download and install JDK
  2. Download and install eclipse
  3. Follow this guide from OpenCV’s website

As for testing, you can use the following code, who will do the exact same thing as in the C++ version. You may note that this code is longer than its C++ counterpart. That’s because Java OpenCV doesn’t have equivalent method for imshow() in C++. So, most of the code here are doing image conversion from Mat data type to something that Java can display.

import java.awt.*;						// for ImageIcon type
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import javax.swing.*; 					// for ImageIcon type
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.highgui.Highgui;

// This class displays image 
// Its first function converts from Mat to BufferedImage
// Second function displays the converted image
class ImageDisplayer
{
   public BufferedImage Mat2BufferedImage(Mat m)
   {
		//source: http://answers.opencv.org/question/10344/opencv-java-load-image-to-gui/
		//Fastest code
		//The output can be assigned either to a BufferedImage or to an Image
	
	   int type = BufferedImage.TYPE_BYTE_GRAY;
	   if ( m.channels() > 1 ) {
	       type = BufferedImage.TYPE_3BYTE_BGR;
	   }
	   int bufferSize = m.channels()*m.cols()*m.rows();
	   byte [] b = new byte[bufferSize];
	   m.get(0,0,b); // get all the pixels
	   BufferedImage image = new BufferedImage(m.cols(),m.rows(), type);
	   final byte[] targetPixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
	   System.arraycopy(b, 0, targetPixels, 0, b.length);  
	   return image;	
   }
   
   public void displayImage(Image img2)
   {   
	   ImageIcon icon=new ImageIcon(img2);
	   JFrame frame=new JFrame();
	   frame.setLayout(new FlowLayout());        
	   frame.setSize(img2.getWidth(null)+50, img2.getHeight(null)+50);     
	   JLabel lbl=new JLabel();
	   lbl.setIcon(icon);
	   frame.add(lbl);
	   frame.setVisible(true);
	   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
}

// This is the main class
// We load image using OpenCV as a Mat
public class hello
{
	public static void main( String[] args )
	{
	    System.loadLibrary( Core.NATIVE_LIBRARY_NAME );
		Mat img = Highgui.imread("C:\\Users\\Didit\\Pictures\\fifa.png"); //Change to any file you want
	    ImageDisplayer displayer = new ImageDisplayer();
		Image imgToShow = displayer.Mat2BufferedImage(img);
	    displayer.displayImage(imgToShow);
	}
}

I didn’t actually notice that there would be so much code in the beginning, but Java is pretty easy to read anyway. So, I don’t think this trade off should scare you from using OpenCV in Java.

Installing C++ OpenCV in Visual Studio 2012 for Windows 7

Let’s make it quick, here are the steps required. I use pre-build OpenCV 2.4.11 in a 64-bit Windows 7 machine.

Getting The OS Ready
First of all, let’s download OpenCV and do some OS-level configurations

  1. Download OpenCV
  2. Extract OpenCV to your desired folder. It’s a good idea to use the shortest path to it and keeping the version name too. Example: “D:\OpenCV-2.4.11”
  3. Open Command Prompt and type
    setx -m OPENCV_DIR D:\OpenCV\Build\x64\vc11 

    Note that this is for 64-bit Visual Studio 2012

  4. Right click on My Computer, click Properties and choose Advanced System Settings
  5. Click Environment Variables button
  6. In System variables, choose the Path Variable and click Edit button
  7. Now, type
    ;%OPENCV_DIR%\bin;

    At this point, the system knows where OpenCV is. If you need to change the directory, you just need to redo step 3 and change accordingly

Adding OpenCV to Visual Studio Project
Now, we’ll look into how to add OpenCV to a Visual Studio project. It involves adding the appropriate libraries, header files and DLLs.

Note that the official tutorial from OpenCV also suggests global mode of adding libraries. I prefer local method. For the sake of completion, I’d suggest that you go and visit that page

  1. Open Visual Studio, choose File – New Project
  2. Choose Win32 Console Application, give it a name and choose where to save it. Click Next
  3. In the next wizard window, choose Empty Project under Additional Options, just to make things cleaner. This is optional though.
  4. Now you have a basic project ready to be used. Let’s add OpenCV to it.
  5. Go to Project-$Project_Name Properties or press Alt+F7
  6. Because I want to use 64-bit, I go to Configuration Manager and change the platform to x64
  7. Next, in the Property Pages window, choose Configuration PropertiesC/C++ and under Additional Include Directories insert:
    $(OPENCV_DIR)\..\..\include
    $(OPENCV_DIR)\..\..\include\opencv2
    $(OPENCV_DIR)\..\..\include\opencv2
    
  8. Then, in Linker – Additional Library Directories insert
    $(OPENCV_DIR)\lib
  9. Now, check your Configuration on top of the Property Pages window. You can set it for Debug or Release. Make sure that you have these additional libraries for both configuration.
  10. For Debug configuration, in Linker – Input – Additional Dependencies insert these following items:
    opencv_calib3d2411d.lib
    opencv_core2411d.lib
    opencv_features2d2411d.lib
    opencv_flann2411d.lib
    opencv_highgui2411d.lib
    opencv_imgproc2411d.lib
    opencv_ml2411d.lib
    opencv_objdetect2411d.lib
    opencv_photo2411d.lib
    opencv_stitching2411d.lib
    opencv_superres2411d.lib
    opencv_ts2411d.lib
    opencv_video2411d.lib
    opencv_videostab2411d.lib
    
  11. And finally, for release, repeat the last step, insert aforementioned items, but remove the letter “d” before lib, so you have:
    opencv_calib3d2411.lib
    opencv_core2411.lib
    opencv_features2d2411.lib
    opencv_flann2411.lib
    opencv_highgui2411.lib
    opencv_imgproc2411.lib
    opencv_ml2411.lib
    opencv_objdetect2411.lib
    opencv_photo2411.lib
    opencv_stitching2411.lib
    opencv_superres2411.lib
    opencv_ts2411.lib
    opencv_video2411.lib
    opencv_videostab2411.lib
    

That’s it, you now have a working OpenCV libraries in Visual Studio. You may want to save it as a template, so you don’t have to repeat it all over again.

Testing The Installation
Now for the fun part, let’s add a source code and compile it. We’ll make a simple image viewer using OpenCV. Add a new C++ file, name it anything. Type in the following code

// Simple image display using OpenCV

// Include opencv
#include <opencv2\opencv.hpp>
#include <opencv2\highgui\highgui.hpp>

void main()
{
	cv::Mat img = cv::imread("your image file here");// for example C:\\pictures\\image.jpg
	cv::imshow("image", img);
	cv::waitKey(); // so the program doesn't close directly.
}

Now build it, and see the image. If everything’s fine you should see an image being displayed.
Congratulations! You now have a working OpenCV installation in Visual Studio 2012. Now go and make something exciting.

Installing OpenCV in Windows 7

I’ll be teaching Computer Vision next semester using OpenCV as the programming tool. Though I’ve been using it couple of times in the past, I think it would be better if I switch to Windows for the sake of teaching, since most of my students use that OS. Therefore, they can focus on the makn thing, the theory and practice of computer vision.

Now, since they’ve used C++ and Java (through Processing) in the past, I then have several options to setup the dev machine:

  1. OpenCV in C++ using Visual Studio 2012
  2. OpenCV in Java using Eclipse
  3. OpenCV in Java using Processing IDE

I will cover the installation process for these three options, mainly because I need a single place of reference for similar activity in the future (i.e. less Googling).

Initial Steps
Some notes to read regarding the environment

  1. This guide uses OpenCV 2.4.11. Make sure you download it from the OpenCV website. I may use 3.0.0 in the future, but for now, this is enough.
  2. For the sake of getting the environment up and running quickly, I use the pre-build OpenCV. You’re free to build from source, as in the end, you’ll end up using the same files.
  3. I use Windows 7 64-bit, but I think this should work for Windows 8 too.

Main Menu
Generally speaking, our installation involves these steps:

  1. Getting pre-build OpenCV
  2. Importing the OpenCV components (libraries) to the IDE
  3. Testing it by building a simple OpenCV example

To make things easier to read, I’ll separate the scenarios into 3 different blog posts. Happy reading 🙂

    Arduino untuk Pemula Bagian 2: Keajaiban Pemrograman

    Masih menyimpan rangkaian dari tutorial sebelumnya? Kalau iya, bagus. Kalau tidak, silakan baca pelan-pelan dan kembali setelah rangkaiannya siap 🙂

    Jika sudah siap, maka kita bisa memulai bagian kedua tutorial ini. Kali ini, saya akan menunjukkan fleksibilitas dari pemrogaman Arduino. Sebagaimana kita ketahui, Arduino sejatinya adalah sebuah mikrokontroler yang bisa diprogram untuk mengolah input tertentu menjadi sebuah output. Artinya, sebagaimana sebuah komputer yang secara hardware tidak berubah, mampu diprogram untuk melakukan hal-hal yang beragam, maka Arduino juga bisa kita program untuk melakukan hal berbeda, meski terdiri dari komponen yang sama.

    IMG_3669.JPG

    Tutorial kali ini akan difokuskan pada pemrograman Arduino. Tutorial sebelumnya menghasilkan sebuah rangkaian yang terdiri dari tombol dan LED, di mana selama tombol ditekan, maka LED akan menyala. Sangat dasar dan tidak menarik. Kali ini, kita akan membuat LED berkedip jika tombol ditekan, dan mati jika tombol ditekan untuk kedua kalinya. Seperti kita menyalakan saklar. Ini akan kita lakukan dengan menggunakan rangkaian yang sama.

    Kode yang kita gunakan adalah pengembangan dari kode sebelumnya. Hanya ada sedikit penambahan di awal, dan di bagian fungsi loop()

    Bagi yang belum pernah melakukan programming, mungkin ada hal-hal berikut yang perlu disimak:

    1. Setiap baris yang diawali dengan // artinya baris ini adalah komentar, berisi keterangan atau penjelasan tertentu. Bagian ini tidak akan di-compile dan diupload ke Arduino, hanya penjelasan bagi yang membaca source code program tersebut
    2. dalam program, ada yang disebut sebagai variabel. Ini adalah tempat menampung nilai-nilai yang bisa berubah seiring program berjalan. Variabel-variabel ini memiliki tipe tertentu dan akan diinisialisasi dengan memberikan nilai. Sebagai contoh, untuk membuat sebuah variabel dengan nama x yang memiliki tipe data integer (bilangan bulat) dan memiliki nilai 10, kita bisa menulis
    int x = 10

    3. Setiap baris dalam program yang melakukan sebuah hal disebut sebagai pernyataan (statement). Satu pernyataan diakhiri dengan titik koma ;
    4. Ada bagian program yang mengumpulkan satu atau beberapa pernyataan menjadi satu blok tertentu. Ini dikenal sebagai fungsi, dan ia akan melakukan tugas tertentu. Sebagai contoh di program kita, ada 2 buah fungsi, yakni setup() dan loop()

    Yak, inilah kodenya:

    // set pin nomor 2 sebagai pin button dan pin 13 sebagai pin untuk LED
    const int buttonPin = 2;
    const int ledPin = 13;
    
    // membuat variabel untuk menyimpan status tombol, status sebelumnya, dan status LED
    int buttonState = LOW;
    int prevButtonState = LOW;
    int ledState = LOW;
    
    void setup() {
        // pin ledPin dibuat sebagai output
        pinMode(ledPin, OUTPUT);
        // pin button dibuat sebagai input
        pinMode(buttonPin, INPUT);
    }
    
    void loop(){
        // baca status dari pin button
        buttonState = digitalRead(buttonPin);
    
        // bagian ini akan kita ubah
        // kita memeriksa apakah kondisi button berbeda dengan kondisi sebelumnya
        if (buttonState != prevButtonState) {
            // jika iya, maka kondisi button sebelumnya, adalah kondisi button sekarang
            prevButtonState = buttonState;
            // jika kondisi button sebelumnya LOW, maka status LED akan berbeda dari sebelumnya
            if (prevButtonState == LOW) {
               ledState = !ledState;
            }
        }
        // jika ledState = HIGH, maka LED akan berkedip, jika tidak, maka LED mati
        if (ledState == HIGH) {
            blink();
        } else { 
            digitalWrite (ledPin, ledState);
      }
    }
    
    //fungsi ini membuat lampu LED berkedip
    void blink(){
      digitalWrite(ledPin, HIGH);   // nyalakan LED
      delay(1000);                  // tunggu sebentar
      digitalWrite(ledPin, LOW);    // matikan LED
      delay(1000);                  // tunggu lagi
    }
    

    Kode yang kita ubah dalam fungsi loop() menyatakan bahwa kali ini, yang kita perhatikan adalah perubahan kondisi button. Apabila ada perubahan kondisi, yang terjadi setiap kali ia ditekan, maka variabel ledState akan berubah pula kondisinya. Seperti mengatakan ON atau OFF. Ini berbeda dengan sebelumnya, di mana yang kita perhatikan adalah kondisi button.

    Apabila kondisi LED HIGH, maka program akan memanggil fungsi blink() yang mengatur LED agar berkedip, dan mati jika sebaliknya. Fungsi ini bisa digambarkan sebagai bagian program yang melakukan, well, fungsi tertentu. Setidaknya, dalam Arduino ada 2 fungsi yang wajib ada, yakni setup() yang berjalan sekali di awal program, serta loop() yang dieksekusi berulang-ulang selama program berjalan. Menggunakan fungsi yang berbeda ini adalah latihan yang bagus untuk berpikir prosedural, atau berurutan, yang bisa membantu pemula untuk memecahkan masalah secara terstruktur.

    Itu dia tutorial kali ini, semoga membantu pengalaman menggunakan Arduino. Tutorial selanjutnya akan membahas jenis input yang lain. Jika ada ide, silakan juga tulis komentar pada postingan ini.

    Selamat ngoprek 🙂

    Mengenal Arduino untuk Pemula

    Arduino adalah sebuah platform elektronik yang sangat ramah bagi pemula. Pada intinya, ia adalah sebuah mikrokontroler yang menjembatani berbagai jenis komponen input (sensor) dan output (aktuator). Ia bahkan bisa berinteraksi dengan komputer, memberikan peluang untuk membuat input device di luar mouse atau keyboard. Dengan atau tanpa komputer, keberadaan Arduino telah memungkinkan banyak orang di dunia (termasuk saya) untuk membuat perangkat interaktifnya sendiri. Diagram di bawah ini, menunjukkan bagaimana posisi Arduino sebagai otak dari sebuah perangkat

    Arduino

    Kali ini, saya akan memberikan sedikit pengantar bagaimana menggunakan Arduino untuk pertama kalinya. Percayalah, ini akan mudah, meskipun Anda bukan orang teknik. Saya akan menunjukkan bagaimana input dan output ditangani oleh Arduino.

    Komponen-Komponen yang dibutuhkan
    1. Arduino (jenis apapun)
    2. LED
    3. Button (tombol)
    4. Resistor 220 Ohm
    5. Resistor 10k Ohm
    6. Breadboard
    7. Kabel jumper

    Kita akan membuat rangkaian menggunakan tombol dan LED. Setiap kali tombol dinyalakan, maka LED akan menyala. Untuk mempercepat pembuatan, maka kita akan menggunakan breadboard sebagai tempat membuat rangkaian. Dengan ini, maka kita tidak perlu menyolder.

    Pertama-tama, marilah kita buat rangkaian elektronik kita sebagai berikut:

    Arduino-Button-and-LED_bb

    Di sini kita menggunakan resistor 10k yang terhubung dengan tombol sebagai pull down resistor. Tujuannya untuk menjaga agar logika rangkaian tetap berada dalam kondisi LOW, sehingga lampu akan mati ketika tombol tidak ditekan. Resitor kedua, sebesar 220 Ohm, berfungsi untuk menjaga agar arus listrik yang melewati LED tidak berlebihan. Ini perlu diatur juga, karena arus berlebih bisa menyebabkan komponen dalam rangkaian (termasuk Arduino) rusak. Jangan sampai terbalik juga dalam memasang LED. Ingat, kaki yang pendek, adalah sumbu negatif dan ini dihubungkan dengan pin ground (GND) pada Arduino.

    Secara teknis fisik rangkaian, itu saja yang perlu diperhatikan. Sekarang, mari kita simak kodenya.

    // set pin nomor 2 sebagai pin button dan pin 13 sebagai pin untuk LED
    const int buttonPin = 2;
    const int ledPin = 13;
    
    // membuat variabel untuk menyimpan status tombol
    int buttonState = LOW;
    
    void setup() {
        // pin ledPin dibuat sebagai output
        pinMode(ledPin, OUTPUT);
        // pin button dibuat sebagai input
        pinMode(buttonPin, INPUT);
    }
    
    void loop(){
        // baca status dari pin button
        buttonState = digitalRead(buttonPin);
    
        // periksa apakah button sedang ditekan
        // jika iya, maka
        if (buttonState == HIGH) {
            // LED menyala
            digitalWrite(ledPin, HIGH);
        }
        else {
            // LED mati
            digitalWrite(ledPin, LOW);
        }
    }
    

    Sebelumnya, silakan buka program IDE Arduino yang bisa didownload di situs Arduino. Pilih sesuai sistem operasi Anda, dan ikuti instruksi instalasinya. Jika sudah sukses, maka kita bisa mengetik kode di atas, di IDE Arduino ini.

    Untuk mengupload kode ini, silakan pilih jenis Arduino yang Anda gunakan, beserta serial portnya. Ini untuk membuat IDE Arduino mengcompile dan mengupload kode ke board yang sesuai melalui port yang benar pula.

    Setelah selesai upload, maka voila! Arduino Anda berjalan. Selamat, ini adalah program pertama Arduino yang Anda buat. Tertarik untuk terus mengoprek? Saya akan kembali dengan tutorial santai di lain kesempatan.

    Happy hacking 🙂