<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>GAIBlog</title>
	<atom:link href="http://pebbie.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://pebbie.wordpress.com</link>
	<description>weblog Grafika dan Intelejensia Buatan (GAIB)</description>
	<lastBuildDate>Thu, 26 Jan 2012 13:16:46 +0000</lastBuildDate>
	<language>id</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='pebbie.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>GAIBlog</title>
		<link>http://pebbie.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://pebbie.wordpress.com/osd.xml" title="GAIBlog" />
	<atom:link rel='hub' href='http://pebbie.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Towards Optimal Sample Database for Learning-based Pattern Detector</title>
		<link>http://pebbie.wordpress.com/2012/01/20/optimal-pattern-detection-database/</link>
		<comments>http://pebbie.wordpress.com/2012/01/20/optimal-pattern-detection-database/#comments</comments>
		<pubDate>Fri, 20 Jan 2012 02:56:29 +0000</pubDate>
		<dc:creator>pebbie</dc:creator>
				<category><![CDATA[riset]]></category>
		<category><![CDATA[study]]></category>
		<category><![CDATA[object detection]]></category>
		<category><![CDATA[pattern recognition]]></category>
		<category><![CDATA[sample database]]></category>

		<guid isPermaLink="false">http://pebbie.wordpress.com/?p=555</guid>
		<description><![CDATA[What are the optimal parameters for developing a pattern detector? Pertanyaan itu membuka pagi saya hari ini. Asal-muasal pertanyaan itu muncul dari sebuah pertanyaan pada milis opencv perihal seberapa banyak dan seberapa variatif sampel positif dan negatif yang harus dikumpulkan untuk membuat suatu sistem pendeteksi objek visual secara umum. Hal ini cukup memancing rasa penasaran. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pebbie.wordpress.com&amp;blog=944265&amp;post=555&amp;subd=pebbie&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<blockquote><p>What are the optimal parameters for developing a pattern detector?</p></blockquote>
<p>Pertanyaan itu membuka pagi saya hari ini. Asal-muasal pertanyaan itu muncul dari sebuah pertanyaan pada milis opencv perihal seberapa banyak dan seberapa variatif sampel positif dan negatif yang harus dikumpulkan untuk membuat suatu sistem pendeteksi objek visual secara umum. Hal ini cukup memancing rasa penasaran. Pertama persoalan deteksi merupakan persoalan pengenalan pola (<em>pattern recognition</em>) yang paling sederhana dan batasannya paling longgar jika dibandingkan dengan segmentasi (deteksi batas pola) dan klasifikasi/pengenalan banyak-objek ataupun banyak-kategori/kelas. Persoalan deteksi outputnya biner, yakni hanya ada dua jawaban: ya(ada) atau tidak jika diberikan suatu pola masukan. Sebagai contoh, mata kita sangat sensitif mendeteksi pola wajah. Bahkan mungkin untuk pola yang bukan wajah tapi tampak seperti wajah pun masih dapat dideteksi secara objektif, bukan hanya halusinasi satu orang saja.</p>
<p><span id="more-555"></span></p>
<p>Strategi yang umumnya sekarang ini diambil dalam membuat sistem detektor adalah menggunakan teknik pembelajaran mesin (<em>machine  learning</em>) yang menggunakan metode statistik untuk menganalisis data menjadi sebuah model untuk melakukan pekerjaan deteksi pola tersebut.  Langkah-langkah yang umumnya dilakukan adalah mempersiapkan kumpulan data berisi contoh-contoh pola baik dengan tambahan label sebagai pola acuan yang dibuat oleh manusia maupun tanpa label tetapi pada pengujian hanya diberikan umpan balik apakah kinerja pendeteksiannya lebih baik atau lebih buruk. Cara pertama disebut dengan <em>supervised learning</em> dan cara kedua disebut <em>reinforcement learning</em>. </p>
<p>Adapun panduan untuk mengumpulkan data contoh pada umumnya tidak secara gamblang menjelaskan sampai kondisi apa sebuah koleksi data dikatakan cukup membuat suatu sistem yang berbasis pembelajaran mesin. informasi yang ada hanyalah banyaknya data yang dikumpulkan haruslah <em>cukup banyak</em>. Salah satu metode untuk melakukan justifikasi ini biasanya menggunakan metode statistik. Pada asumsi populasi yang berdistribusi normal secara parametrik, maka generalisasi dilakukan dengan menggunakan limit hampiran (cek teorema limit tengah) lalu sensitivitas detektor sebagai sistem yang dibuat diuji berdasarkan kinerjanya yaitu akurasi dan kemampuan generalisasi berdasarkan jumlah data tadi. Jika diperhatikan, kedua hal ini mirip dengan analogi ayam-telur yakni mana yang duluan? *karena ayam ditulis lebih dulu maka jawabannya jelas ayam* </p>
<p>Persoalan kecukupan data ini tidak hanya terjadi pada sistem yang dibangun dengan metode statistik. Sistem yang dibangun dengan pengembangan pengetahuan heuristik yang diekstrak dari pakar (<em>expert knowledge engineering</em>) pun mengalami persoalan yang sama yaitu seberapa banyak yang dikatakan cukup. Lebih umum lagi seberapa banyak yang diperlukan jika juga mempertimbangkan karakteristik atau sifat dari pola masukan.</p>
<p>Seperti yang dicoba dilakukan oleh para peneliti di bidang teori pola yang berangkat dari teori informasi dan klasifikasi tipe data pada analisis data (statistik), Suatu data atau informasi dapat didekomposisi berdasarkan sifat-sifat intrinsiknya. Sebagai acuan, para matematikawan (khususnya para ahli aljabar) membuat generalisasi yang disebut dengan bilangan tidak hanya pada angka-angka yang selama ini kita kenal melainkan melihat pada struktur aljabar yang terdiri atas objek dan operasi elementer yang dapat  diekstrak relasinya terhadap elemen lain dalam suatu himpunan. Hal ini lalu menjadi basis eksplorasi praktis yaitu untuk analisis data, dan hingga pada waktunya yaitu masa kini kita sudah terbiasa dengan melakukan pengenalan pola dalam berbagai wujud bahkan tidak hanya melakukan pengenalan atau analisis tetapi juga sintesis pola yang dimungkinkan dengan adanya teknologi yang mengamplifikasi kemampuan berpikir manusia yaitu komputer. </p>
<p>Kalau pekerjaan mendeteksi pola ini dilihat dalam kacamata yang lebih luas yaitu bagaimana sistem yang sudah ada (manusia) bekerja, maka mungkin kita akan mendapatkan penjelasan yang lebih baik. Persoalan persepsi merupakan kajian multi-disiplin mulai dari disiplin ilmu kimia yang menjelaskan tentang sifat material. Disiplin ilmu fisika yang menjelaskan bagaimana fenomena-fenomena interaksi antar benda. Disiplin ilmu biologi yang menjelaskan bagaimana organ-organ tubuh manusia bekerja dalam sistem indera dan syaraf. Disiplin ilmu psikologi yang mengkaji bagaimana pikiran sebagai bagian dari jiwa (<em>psyche</em>) bekerja secara fungsional. Hingga disiplin matematika yang membuat formulasi bagaimana pola dianggap sebagai sebuah &#8216;bilangan&#8217; dapat dimanipulasi lewat relasi-relasi dan Informatika dan Rekayasa yang mensimulasikan proses mental yang diperlukan untuk memroses pola yang dikerjakan oleh mesin (komputer). </p>
<p>Kembali ke bahasan awal, jika kita akan membangun suatu koleksi data sebagai bagian dari pengembangan sistem pendeteksi pola maka untuk mendapatkan banyaknya data yang dikatakan &#8216;cukup&#8217; maka beberapa hal harus dipertimbangkan : </p>
<ol>
<li>material dari objek</li>
<li>proses transmisi informasi objek ke sensor (misal objek berinteraksi dengan cahaya ke mata)</li>
<li>proses persepsi yang terjadi pada indera</li>
<li>model abstraksi pola dari informasi yang terlibat pada 1, 2, 3</li>
</ol>
<p>Seharusnya metode untuk melakukan pengenalan dimasukkan jika yang ingin dibuat adalah sistem pendeteksinya. Namun karena pertanyaannya dibatasi pada banyaknya data contoh yang dikatakan cukup, maka metode dihilangkan dari daftar tersebut. </p>
<p>Material objek fisik menentukan seberapa besar ruang kombinatorial pola yang terjadi secara internal objek. Transmisi informasi dan persepsi merupakan proses yang memetakan informasi dari ruang kombinasi pola ke ruang kombinasi pola yang lain. Pada tiap proses pemetaan ada faktor eksternal yang terlibat. Kadang dianggap sebagai gangguan, kadang dianggap sebagai dukungan. Suatu proses dapat dianggap sebagai gangguan jika proses tersebut membuat batasan antara informasi yang satu dengan informasi lainnya pada suatu ruang menjadi semakin sulit dibedakan ataupun adanya penambahan informasi yang tidak relevan. Sebaliknya, suatu proses dianggap sebagai dukungan jika informasi akhir menjadi lebih sederhana dan batasan pembedaan objek menjadi lebih mudah diketahui. </p>
<p>Informasi pada asal dan transformasi yang terjadi pada proses direpresentasikan dengan model abstraksi yang dibuat oleh para matematikawan (objek-objek aljabar seperti bilangan, vektor, graf, dllsb). Bila hal-hal tersebut disederhanakan, maka suatu populasi kombinasi pola yang mungkin ditentukan dari sifat dari objek sumber dan proses-proses transformasi yang terjadi. </p>
<p>Jika kita kembali pada bahasan tentang statistik, maka ada kajian tentang <em>sampling</em>. Proses pengumpulan informasi berupa koleksi contoh untuk membuat sistem pendeteksi pola pada dasarnya adalah proses <em>sampling</em>. Ada banyak metode untuk melakukan sampling. Masing-masing metode dirancang pada umumnya untuk mengurangi bias dan faktor yang dapat meningkatkan risiko validitas suatu kesimpulan yang dibuat dengan menggunakan metode statistik. </p>
<p>Begitu pula dengan pengembangan koleksi data contoh. Pengumpulan data contoh seharusnya tidak hanya menggunakan asumsi banyaknya data, tetapi juga mempertimbangkan karakteristik dari data yang meminimumkan bias-bias yang terjadi pada proses sampling. Dengan demikian, basis data yang dikumpulkan dapat menjadi acuan pengambilan keputusan yang pada akhirnya membantu memilih dan mengembangkan metode-metode pengambilan kesimpulan (dalam hal ini detektor pola) yang berkinerja baik.</p>
<p>Sepertinya tulisan ini sudah semakin dan terlalu panjang. Oleh sebab itu saya akan akhiri sampai sini saja. Beberapa hal yang perlu dibahas selanjutnya antara lain : metode-metode sampling, macam-macam representasi/model pola, hingga akhirnya apa saja metode-metode atau algoritma untuk melakukan klasifikasi data dalam rangka mengembangkan &#8216;the ultimate pattern detector&#8217;.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pebbie.wordpress.com/555/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pebbie.wordpress.com/555/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/pebbie.wordpress.com/555/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/pebbie.wordpress.com/555/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/pebbie.wordpress.com/555/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/pebbie.wordpress.com/555/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/pebbie.wordpress.com/555/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/pebbie.wordpress.com/555/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/pebbie.wordpress.com/555/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/pebbie.wordpress.com/555/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/pebbie.wordpress.com/555/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/pebbie.wordpress.com/555/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/pebbie.wordpress.com/555/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/pebbie.wordpress.com/555/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pebbie.wordpress.com&amp;blog=944265&amp;post=555&amp;subd=pebbie&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://pebbie.wordpress.com/2012/01/20/optimal-pattern-detection-database/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b790f5007b6f9383710eceeabe7b9e33?s=96&#38;d=wavatar&#38;r=X" medium="image">
			<media:title type="html">pebbie</media:title>
		</media:content>
	</item>
		<item>
		<title>Mudah Mengimplementasikan Fasilitas Pencarian dengan Python Whoosh</title>
		<link>http://pebbie.wordpress.com/2011/12/14/mudah-mengimplementasikan-fasilitas-pencarian-dengan-python-whoosh/</link>
		<comments>http://pebbie.wordpress.com/2011/12/14/mudah-mengimplementasikan-fasilitas-pencarian-dengan-python-whoosh/#comments</comments>
		<pubDate>Wed, 14 Dec 2011 12:01:32 +0000</pubDate>
		<dc:creator>pebbie</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[full text search]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://pebbie.wordpress.com/?p=548</guid>
		<description><![CDATA[Beberapa waktu lalu saya sempat membutuhkan mekanisme pencarian terhadap kumpulan dokumen teks. Beberapa alternatif yang populer diantaranya Apache Lucene (Solr) dan Sphinx search. Lucene berlisensi Apache License, Sphinx GPL. Keduanya ditulis dalam bahasa JAVA (OK, BIG NO). Setelah kesana-kemari mencari akhirnya ketemu alternatif yang cukup menarik yaitu Whoosh. library ini ditulis dalam pure python, berlisensi [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pebbie.wordpress.com&amp;blog=944265&amp;post=548&amp;subd=pebbie&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p align="justify">Beberapa waktu lalu saya sempat membutuhkan mekanisme pencarian terhadap kumpulan dokumen teks. Beberapa alternatif yang populer diantaranya Apache Lucene (Solr) dan Sphinx search. Lucene berlisensi Apache License, Sphinx GPL. Keduanya ditulis dalam bahasa JAVA (OK, BIG NO). Setelah kesana-kemari mencari akhirnya ketemu alternatif yang cukup menarik yaitu <a href="http://pypi.python.org/pypi/Whoosh/">Whoosh</a>. library ini ditulis dalam pure python, berlisensi BSD, cepat, dan mudah digunakan.</p>
<blockquote><p>Whoosh is a fast, featureful full-text indexing and searching library<br />
implemented in pure Python. Programmers can use it to easily add search<br />
functionality to their applications and websites. Every part of how Whoosh<br />
works can be extended or replaced to meet your needs exactly.</p></blockquote>
<p><span id="more-548"></span></p>
<p align="justify">Whoosh bisa diunduh di situs <a href="http://pypi.python.org/pypi/Whoosh/">pypi</a> atau di repositori di <a href="http://bitbucket.org/mchaput/whoosh">bitbucket</a> (Mercurial). Setelah dipasang, whoosh bisa digunakan dengan kode pendek berikut</p>
<p><pre class="brush: python;">
from whoosh.index import create_in, open_dir
from whoosh.fields import *
</pre></p>
<p align="justify">Hal pertama yang perlu dilakukan sebelum mengindeks dokumen adalah membuat <em>schema</em>. Schema digunakan untuk mendefinisikan struktur indeks yang akan disimpan oleh Whoosh. Skema sederhana berikut bisa dijadikan contoh. Pilihan <strong>stored</strong> menyatakan bahwa elemen ini akan dikembalikan dalam hasil pencarian.</p>
<p><pre class="brush: python;">schema = Schema(title=TEXT(stored=True), path=TEXT(stored=True), content=TEXT)</pre></p>
<p align="justify">Setelah skema indeks didefinisikan langkah selanjutnya adalah membuat indeks. Whoosh menggunakan indeks yang disimpan pada filesystem (Whoosh tidak menggunakan database umum). Fungsi <strong>create_in</strong> disediakan sebagai jalan pintas dari membuat objek file indeks.</p>
<p><pre class="brush: python;">_ix = create_in('indexdir', schema)
w = _ix.writer()

#telusuri direktori untuk mencari file teks
for root, dirnames, filenames in os.walk('data'):
    for filename in fnmatch.filter(filenames, '*.txt'):
        doc = os.path.join(root, filename)
        f = open(doc)
        text = f.read()
        w.add_document(title=unicode(filename[:-4]), content=unicode(text), path=unicode(doc))
        f.close()

    w.commit()</pre></p>
<p align="justify">Pada kasus di atas, saya memberi nama file sesuai dengan judulnya. Proses di atas terdiri dari 3 langkah yaitu :
<ol>
<li>memanggil objek IndexWriter</li>
<li>menambahkan item/dokumen</li>
<li>melakukan <strong>commit</strong></li>
</ol>
<p align="justify">Jika ada dokumen baru yang ingin ditambahkan maka pola di atas juga dapat langsung digunakan tapi tidak perlu lagi melakukan pembuatan indeks melalui <strong>create_in</strong>. Jika direktori indeks sudah dibuat maka objek Index dapat dipanggil dengan fungsi <strong>open_dir</strong>.</p>
<p><pre class="brush: python;">_ix = open_dir('indexdir')</pre></p>
<p>Untuk melakukan Pencarian dari indeks, dapat menggunakan objek IndexSearcher yang dipanggil dari objek indeks menggunakan</p>
<p><pre class="brush: python;">    s = _ix.searcher()
    q = QueryParser('content', _ix.schema).parse(unicode(qs))
    r = s.search(q)
    for rr in r:
        print rr
    s.close()</pre></p>
<p>Nah! cukup begitu saja untuk menambahkan hasil pencarian. Pembuatan indeks pun dilakukan dengan cepat.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pebbie.wordpress.com/548/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pebbie.wordpress.com/548/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/pebbie.wordpress.com/548/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/pebbie.wordpress.com/548/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/pebbie.wordpress.com/548/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/pebbie.wordpress.com/548/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/pebbie.wordpress.com/548/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/pebbie.wordpress.com/548/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/pebbie.wordpress.com/548/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/pebbie.wordpress.com/548/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/pebbie.wordpress.com/548/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/pebbie.wordpress.com/548/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/pebbie.wordpress.com/548/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/pebbie.wordpress.com/548/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pebbie.wordpress.com&amp;blog=944265&amp;post=548&amp;subd=pebbie&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://pebbie.wordpress.com/2011/12/14/mudah-mengimplementasikan-fasilitas-pencarian-dengan-python-whoosh/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b790f5007b6f9383710eceeabe7b9e33?s=96&#38;d=wavatar&#38;r=X" medium="image">
			<media:title type="html">pebbie</media:title>
		</media:content>
	</item>
		<item>
		<title>Mempercepat Operasi OpenCV di Python dengan scipy.weave</title>
		<link>http://pebbie.wordpress.com/2011/11/27/mempercepat-operasi-opencv-di-python-dengan-scipy-weave/</link>
		<comments>http://pebbie.wordpress.com/2011/11/27/mempercepat-operasi-opencv-di-python-dengan-scipy-weave/#comments</comments>
		<pubDate>Sun, 27 Nov 2011 12:08:11 +0000</pubDate>
		<dc:creator>pebbie</dc:creator>
				<category><![CDATA[computer vision]]></category>
		<category><![CDATA[hacking]]></category>
		<category><![CDATA[image processing]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[inline]]></category>
		<category><![CDATA[lbp]]></category>
		<category><![CDATA[opencv]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[scipy]]></category>
		<category><![CDATA[scipy.weave]]></category>

		<guid isPermaLink="false">http://pebbie.wordpress.com/?p=541</guid>
		<description><![CDATA[Tadi pagi saya mencoba menerapkan kode tentang LBP (Local Binary Pattern) dari yang tadinya hanya memroses satu citra menjadi memroses tiap frame pada video. Saya mencoba LBP lebih dahulu dibanding HOG karena berdasarkan kode yang dibuat sebelumnya, waktu eksekusi HOG memang lebih lambat dibanding LBP. Namun ternyata waktu eksekusi perhitungan fitur LBP cukup berat yang [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pebbie.wordpress.com&amp;blog=944265&amp;post=541&amp;subd=pebbie&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p align="justify">Tadi pagi saya mencoba menerapkan kode tentang LBP (Local Binary Pattern) dari yang tadinya hanya memroses satu citra menjadi memroses tiap frame pada video. Saya mencoba LBP lebih dahulu dibanding HOG karena berdasarkan kode yang dibuat sebelumnya, waktu eksekusi HOG memang lebih lambat dibanding LBP. Namun ternyata waktu eksekusi perhitungan fitur LBP cukup berat yang membuat frekuensi penggambarannya turun hingga 1 frame per detik! Setelah diidentifikasi ternyata perulangan bersarang (nested loop) di python sangat lambat walaupun sudah menggunakan generator function xrange. Akhirnya teringat kode yang dibuat oleh <a href="http://code.google.com/p/haines/">Tom Haines</a> yang memanfaatkan modul weave dalam paket scipy yang mempermudah membuat kode inline dalam bahasa C++ yang akan dikompilasi pada saat run-time sehingga yang dijalankan adalah kode native tanpa harus membuat kode dalam file terpisah. </p>
<p align="justify">Di awal-awal mencoba dengan hanya bermodalkan google, sempat seringkali gagal compile. kegagalan pertama, scipy.weave akan mencari compiler MS Visual C++ sehingga saya harus memaksa untuk menggunakan gcc. Kesalahan berikutnya adalah gagal compile. Perjuangan masih berlanjut ketika kode sudah berhasil dikompilasi, tetapi Image tidak berubah padahal di dalam kode inline nilainya sudah berubah. Hal lain yang perlu dicatat adalah saya mulai menggunakan interface opencv versi 2 (cv2) yang sudah terintegrasi dengan numpy karena untuk melakukan manipulasi piksel dengan menggunakan scipy.weave lebih memudahkan untuk menggunakan representasi numpy.array dibandingkan dengan IplImage (ya iyalah, scipy kan pake numpy). </p>
<p align="justify">OK, Pembahasan akan saya mulai dengan penggunaan fungsi inline dari scipy.weave. Perhatikan kode berikut:</p>
<p><pre class="brush: python;">import cv, cv2
import numpy as np
from scipy.weave import inline

MASK = np.array([[0,-1],[1,-1],[1,0],[1,1],[0,1],[-1,-1],[-1,0],[-1,1]])
def calc_lbp(src, dst):
    code = r&quot;&quot;&quot;
        for (int y=1; y&lt;Nsrc[0]-1; ++y){
            for (int x=1; x&lt;Nsrc[1]-1; ++x){
                unsigned char px = SRC2(y,x);
                unsigned char n = 0;
                for(int m=0; m&lt;8; ++m) 
                    if(SRC2(y+MASK2(m,1),x+MASK2(m,0))&gt;px) 
                        n |= 1 &lt;&lt; m;
                DST2(y,x) = n;
            }
        }
    &quot;&quot;&quot;
    inline(code, ['src','dst','MASK'], compiler='gcc')
    return dst
</pre><br />
<span id="more-541"></span></p>
<p align="justify">parameter src dan dst merupakan objek numpy.array. kode ditulis dalam string, lalu beberapa variabel ditransfer ke dalam kode C++ yang akan digenerate dan dikompilasi pada saat pertama kali dipanggil lalu disimpan dalam disk cache sehingga jika dilakukan pemanggilan berikutnya yang dijalankan adalah kode yang sudah terkompilasi (baca: jauh lebih cepat!). Pada kode tersebut saya tidak mentransfer dimensi dari array src dan dst karena pada saat pembangkitan kode C++, scipy.weave akan membuat variabel-variabel yang memudahkan mengakses data dari objek numpy.array diantaranya N{nama-variabel-array} yaitu array yang berisi banyaknya elemen tiap dimensi array, D{nama-variabel-array} yang berupa nilai integer yang menyatakan dimensi array tersebut. Pada contoh kode di atas, variabel Nsrc merupakan variabel yang disediakan untuk mengakses banyaknya elemen pada tiap dimensi array src (misal untuk array 2 dimensi row-wise, Nsrc[0] untuk banyaknya baris dan Nsrc[1] menunjukkan banyaknya kolom, Dsrc bernilai 2). Untuk mengakses elemen dari array  (get/set) disediakan MACRO-MACRO tambahan dengan format {nama-variabel-array-uppercase}{dimensi}({indeks}). Pada kode di atas, array src dan dst berdimensi 2 sehingga untuk mengakses elemennya menggunakan SRC2(i,j) dan DST2(i,j). Kalau src adalah array berdimensi satu maka elemennya diakses menggunakan MACRO SRC1(i). kalau parameter compiler tidak diisi maka compiler yang digunakan dalam lingkungan windows adalah MSVC.</p>
<p>Kode sisanya adalah membaca berkas video, dan menampilkan hasil eksekusi fungsi lbp di atas ke dalam windownya sendiri.<br />
<pre class="brush: python;">
#...lanjutan kode di atas

filename = r&quot;tol2.avi&quot;
cap = cv2.VideoCapture(filename)
if not cap.isOpened(): 
    print &quot;capture failed&quot;
    exit()
f, im = cap.read()
gr = cv2.cvtColor(im, cv.CV_BGR2GRAY)
lbp = cv2.cvtColor(im, cv.CV_BGR2GRAY)

calc_lbp(gr, lbp) #panggilan pertama agak lambat karena harus memanggil kompilator gcc

while True:
    f, im = cap.read()
    if not f:
        cap = cv2.VideoCapture(filename)
        f, im = cap.read()
    cv2.cvtColor(im, cv.CV_BGR2GRAY, gr)
    
    calc_lbp(gr, lbp) #pemanggilan berikutnya jauh lebih cepat (menjalankan ekstensi native)
  
    cv2.imshow(&quot;lbp&quot;, lbp)
    cv2.imshow(&quot;img&quot;, im)
    cv2.imshow(&quot;gr&quot;, gr)
    
    key = cv2.waitKey(1)
    if key == 27:
        break
</pre></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pebbie.wordpress.com/541/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pebbie.wordpress.com/541/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/pebbie.wordpress.com/541/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/pebbie.wordpress.com/541/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/pebbie.wordpress.com/541/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/pebbie.wordpress.com/541/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/pebbie.wordpress.com/541/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/pebbie.wordpress.com/541/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/pebbie.wordpress.com/541/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/pebbie.wordpress.com/541/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/pebbie.wordpress.com/541/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/pebbie.wordpress.com/541/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/pebbie.wordpress.com/541/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/pebbie.wordpress.com/541/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pebbie.wordpress.com&amp;blog=944265&amp;post=541&amp;subd=pebbie&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://pebbie.wordpress.com/2011/11/27/mempercepat-operasi-opencv-di-python-dengan-scipy-weave/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b790f5007b6f9383710eceeabe7b9e33?s=96&#38;d=wavatar&#38;r=X" medium="image">
			<media:title type="html">pebbie</media:title>
		</media:content>
	</item>
		<item>
		<title>Local Binary Pattern in OpenCV (Python)</title>
		<link>http://pebbie.wordpress.com/2011/11/10/local-binary-pattern-in-opencv-python/</link>
		<comments>http://pebbie.wordpress.com/2011/11/10/local-binary-pattern-in-opencv-python/#comments</comments>
		<pubDate>Thu, 10 Nov 2011 16:08:02 +0000</pubDate>
		<dc:creator>pebbie</dc:creator>
				<category><![CDATA[computer vision]]></category>
		<category><![CDATA[hacking]]></category>
		<category><![CDATA[image processing]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[lbp]]></category>
		<category><![CDATA[local binary pattern]]></category>
		<category><![CDATA[opencv]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[texture descriptor]]></category>

		<guid isPermaLink="false">http://pebbie.wordpress.com/?p=526</guid>
		<description><![CDATA[Masih melanjutkan tulisan sebelumnya, sengaja disambung karena isinya sangat sederhana (gatal kalau tidak ditulis). LBP (Local Binary Pattern) atau Pola Biner Lokal merupakan salah satu informasi yang dapat dianalisis dari citra. Informasi LBP biasanya digunakan sebagai deksriptor dari tekstur. Salah satu kelebihan dari LBP adalah sifatnya yang invarian terhadap perubahan fotometri dari objek yang sama [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pebbie.wordpress.com&amp;blog=944265&amp;post=526&amp;subd=pebbie&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p align="justify">Masih melanjutkan tulisan sebelumnya, sengaja disambung karena isinya sangat sederhana (gatal kalau tidak ditulis). LBP (Local Binary Pattern) atau Pola Biner Lokal merupakan salah satu informasi yang dapat dianalisis dari citra. Informasi LBP biasanya digunakan sebagai deksriptor dari tekstur. Salah satu kelebihan dari LBP adalah sifatnya yang invarian terhadap perubahan fotometri dari objek yang sama karena sifatnya yang merupakan ukuran intensitas relatif suatu piksel dengan intensitas piksel di sekitarnya.</p>
<p><span id="more-526"></span></p>
<p align="justify">istilah biner berasal dari representasi kenisbian intensitas piksel tetangga terhadap piksel yang sedang diproses. LBP dihitung dengan mengasosiasikan sejumlah ketetanggaan dengan bit-bit pada angka. Misalkan, untuk area ketetanggaan 3&#215;3 piksel maka piksel yang ada di tengah akan memiliki tetangga sebanyak 8 piksel. Suatu posisi bit akan bernilai 1 jika intensitas piksel tetangga lebih besar daripada piksel yang sedang diproses (piksel tengah). Setiap piksel tetangga diasosiasikan dengan satu posisi bit sehingga untuk ketetanggan 3&#215;3 (8 tetangga) tersebut maka setiap piksel yang diproses akan memiliki variasi tetangga sebanyak 2^8 = 255 kombinasi.</p>
<p>Implementasi algoritma menghitung fitur LBP diperlihatkan pada kode (python) berikut.<br />
<pre class="brush: python;">import cv

def calc_lbp(im):
    &quot;&quot;&quot;
    calculate LBP (Local Binary Pattern) image N8 neighborhood
    &quot;&quot;&quot;
    sz = cv.GetSize(im)
    gr = cv.CreateImage(sz, 8, 1)
    lbp = cv.CreateImage(sz, 8, 1)
    
    #convert to grayscale
    cv.CvtColor(im, gr, cv.CV_BGR2GRAY)

    LBPMASK = [(0,-1),(1,-1),(1,0),(1,1),(0,1),(-1,-1),(-1,0),(-1,1)]
    
    for y in xrange(1, sz[1]-2):
        for x in xrange(1, sz[0]-2):
            n = 0
            gv = gr[y,x]
            for i in xrange(len(LBPMASK)):
                m = LBPMASK[i]
                if gr[y+m[1], x+m[0]]&gt;gv:
                    n += 1 &lt;&lt; i
            lbp[y,x] = n
            
    return lbp

if __name__ == '__main__':
    im = cv.LoadImage('jalan2.jpg')

    lbpim = calc_lbp(im)
    cv.ShowImage('lbp', lbpim)

    key = cv.WaitKey(0)
</pre></p>
<p>Untuk menunjukkan efek dari kode di atas, saya akan menggunakan gambar yang sama dengan tulisan sebelumnya.</p>
<div id="attachment_519" class="wp-caption alignnone" style="width: 310px"><a href="http://pebbie.files.wordpress.com/2011/11/jalan2.jpg"><img src="http://pebbie.files.wordpress.com/2011/11/jalan2.jpg?w=300&#038;h=225" alt="citra asal" title="jalan2" width="300" height="225" class="size-medium wp-image-519" /></a><p class="wp-caption-text">citra asal</p></div>
<div id="attachment_527" class="wp-caption alignnone" style="width: 310px"><a href="http://pebbie.files.wordpress.com/2011/11/jalan2_lbp.jpg"><img src="http://pebbie.files.wordpress.com/2011/11/jalan2_lbp.jpg?w=300&#038;h=233" alt="" title="jalan2_lbp" width="300" height="233" class="size-medium wp-image-527" /></a><p class="wp-caption-text">ekstraksi fitur LBP</p></div>
<p align="justify">Dalam beberapa paper yang saya baca, fitur LBP ini dikombinasikan dengan fitur HOG untuk menghasilkan sistem pendeteksi yang lebih akurat. Pemrosesan lebih lanjut dengan PCA dilakukan untuk mereduksi dimensi vektor yang perlu diproses untuk membandingkan dan ternyata (di paper yang saya baca) melaporkan bahwa hasil pendeteksiannya menjadi lebih akurat. Mari kita buktikan apakah laporan itu benar atau tidak. tunggu tulisan selanjutnya!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pebbie.wordpress.com/526/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pebbie.wordpress.com/526/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/pebbie.wordpress.com/526/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/pebbie.wordpress.com/526/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/pebbie.wordpress.com/526/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/pebbie.wordpress.com/526/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/pebbie.wordpress.com/526/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/pebbie.wordpress.com/526/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/pebbie.wordpress.com/526/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/pebbie.wordpress.com/526/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/pebbie.wordpress.com/526/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/pebbie.wordpress.com/526/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/pebbie.wordpress.com/526/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/pebbie.wordpress.com/526/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pebbie.wordpress.com&amp;blog=944265&amp;post=526&amp;subd=pebbie&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://pebbie.wordpress.com/2011/11/10/local-binary-pattern-in-opencv-python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b790f5007b6f9383710eceeabe7b9e33?s=96&#38;d=wavatar&#38;r=X" medium="image">
			<media:title type="html">pebbie</media:title>
		</media:content>

		<media:content url="http://pebbie.files.wordpress.com/2011/11/jalan2.jpg?w=300" medium="image">
			<media:title type="html">jalan2</media:title>
		</media:content>

		<media:content url="http://pebbie.files.wordpress.com/2011/11/jalan2_lbp.jpg?w=300" medium="image">
			<media:title type="html">jalan2_lbp</media:title>
		</media:content>
	</item>
		<item>
		<title>Computing HOG Features in OpenCV (Python)</title>
		<link>http://pebbie.wordpress.com/2011/11/10/computing-hog-features-in-opencv-python/</link>
		<comments>http://pebbie.wordpress.com/2011/11/10/computing-hog-features-in-opencv-python/#comments</comments>
		<pubDate>Thu, 10 Nov 2011 15:21:31 +0000</pubDate>
		<dc:creator>pebbie</dc:creator>
				<category><![CDATA[computer vision]]></category>
		<category><![CDATA[hacking]]></category>
		<category><![CDATA[image processing]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[hog]]></category>
		<category><![CDATA[opencv]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://pebbie.wordpress.com/?p=515</guid>
		<description><![CDATA[Sudah lama tidak menulis di blog *hiyaaa* karena masih beradaptasi dengan aktivitas sebagai dosen (yang tidak cuma mengajar dan meneliti, &#8220;maklumlah dosen muda, kalau kata dosen-dosen lain yang sudah lebih senior&#8221;). Padahal banyak sekali yang mau ditulis (dan dikerjakan tentunya). Curhatnya saya hentikan sampai sini saja. Ceritera mengenai pengalaman saya dalam menjalani aktivitas sebagai dosen [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pebbie.wordpress.com&amp;blog=944265&amp;post=515&amp;subd=pebbie&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p align="justify">Sudah lama tidak menulis di blog *hiyaaa* karena masih beradaptasi dengan aktivitas sebagai dosen (yang tidak cuma mengajar dan meneliti, &#8220;maklumlah dosen muda, kalau kata dosen-dosen lain yang sudah lebih senior&#8221;). Padahal banyak sekali yang mau ditulis (dan dikerjakan tentunya).</p>
<p align="justify">Curhatnya saya hentikan sampai sini saja. Ceritera mengenai pengalaman saya dalam menjalani aktivitas sebagai dosen saya tuliskan di blog kampus. tulisan-tulisan di sini akan tetap saya fokuskan pada hasil utak-atik (terutama kode <em>proof-of-concept</em>) dalam mempelajari topik-topik dalam dunia informatika.</p>
<p align="justify">Kali ini saya sedang iseng membuat implementasi dari HOG (Histogram of Oriented Gradients). Fitur ini dikaji secara lebih dalam oleh Navneet Dalal dan Bill Triggs dari INRIA, Perancis untuk mendeteksi pejalan kaki (<em>pedestrian</em>) pada citra di tahun 2005. Sama seperti deskriptor yang digunakan pada SIFT (Scale Invariant Feature Transform *eh, saya belum membahas SIFT ya?*), informasi vektor gradien disimpan dalam koordinat polar (panjang dan arah).</p>
<p align="justify">Walaupun HOG *katanya* sudah ada di OpenCV tapi di dokumentasi python sepertinya belum ditambahkan. Python ini sedikit dianaktirikan di OpenCV, saya baru bisa menikmati fasilitas SVM di python di versi 2.3 (dengan python 2.6), karena OpenCV versi 2.2 untuk python hanya berisi modul untuk python versi 2.7. Akhirnya saya terpaksa membuat sendiri. Sebetulnya pembuatan HOG di OpenCV <em>from scratch</em> sudah pernah ditulis oleh Saurabh Goyal di <a href="http://smsoftdev-solutions.blogspot.com/2009/08/integral-histogram-for-fast-calculation.html">sini</a>. Apa yang saya buat mengadopsi dari yang sudah ditulis di sana (dengan modifikasi sesuka saya tentunya) terutama bagian penghitungan dengan memanfaatkan <a href="http://en.wikipedia.org/wiki/Summed_area_table">citra integral</a>. Kode yang ditulis dengan python menurut saya jadi lebih sederhana dan (semoga) lebih mudah dibaca dan dipahami oleh pembaca (setia?) blog ini. Selamat menikmati <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><span id="more-515"></span></p>
<p align="justify">Mari kita buka bahasan kita dengan kode dalam python yang akan saya jelaskan setelahnya. Saya menggunakan dua modul yaitu cv(opencv) dan numpy (dengan alias np).</p>
<p><pre class="brush: python;">import cv
import numpy as np

def calc_hog(im,numorient=9):
    &quot;&quot;&quot;
    calculate integral HOG (Histogram of Orientation Gradient) image (w,h,numorient)
    
    calc_hog(im, numorient=9)
    
    returns 
        Integral HOG image

    params 
        im : color image
        numorient : number of orientation bins, default is 9 (-4..4)
    
    &quot;&quot;&quot;
    sz = cv.GetSize(im)
    gr = cv.CreateImage(sz, 8, 1)
    gx = cv.CreateImage(sz, 32, 1)
    gy = cv.CreateImage(sz, 32, 1)
    
    #convert to grayscale
    cv.CvtColor(im, gr, cv.CV_BGR2GRAY)
    
    #calc gradient using sobel
    cv.Sobel(gr, gx, 1, 0, 3)
    cv.Sobel(gr, gy, 0, 1, 3)
    
    #calc initial result
    hog = np.zeros((sz[1], sz[0], numorient))
    mid = numorient/2
    for y in xrange(0, sz[1]-1):
        for x in xrange(0, sz[0]-1):
            angle = int(round(mid*np.arctan2(gy[y,x], gx[y,x])/np.pi))+mid
            magnitude = np.sqrt(gx[y,x]*gx[y,x]+gy[y,x]*gy[y,x])
            hog[y,x,angle] += magnitude
            
            
    #build integral image
    for x in xrange(1, sz[0]-1):
        for ang in xrange(numorient):
            hog[y,x,ang] += hog[y,x-1,ang]
    for y in xrange(1, sz[1]-1):
        for ang in xrange(numorient):
            hog[y,x,ang] += hog[y-1,x,ang]
    for y in xrange(1, sz[1]-1):
        for x in xrange(1, sz[0]-1):
            for ang in xrange(numorient):
                #tambah kiri dan atas, kurangi dengan kiri-atas
                hog[y,x,ang] += hog[y-1,x,ang] + hog[y,x-1,ang] - hog[y-1,x-1,ang]
    return hog
</pre></p>
<p align="justify">beberapa langkah yang dilakukan dalam membuat citra hog integral a.l.:</p>
<ul>
<li>menghitung citra gradien dengan memanfaatkan operator sobel</li>
<li>membuat citra histogram untuk menampung diskretisasi sudut/orientasi (sebanyak orientasi yang diperlukan, harus berjumlah ganjil), saya memanfaatkan array dari numpy.</li>
<li>membuat citra integral terhadap setiap orientasi.</li>
</ul>
<p align="justify">Pada contoh kode di atas, saya membuat array berdimensi 3 berukuran lebar citra x tinggi citra x banyaknya elemen orientasi yang diinginkan. banyaknya orientasi selalu ganjil supaya simetris dalam menskalakan perhitungan sudut orientasi (misal -n div 2,&#8230;,-1, 0, 1,&#8230;,n div 2). citra 3 dimensi ini juga bisa didekomposisi menjadi kumpulan citra sebanyak <strong>n</strong> yang masing-masing mewakili tiap sudut.</p>
<p align="justify">penggunaan citra integral akan memudahkan untuk membuat fitur HOG dalam berbagai skala resolusi karena kompleksitas komputasi untuk menghitung fitur HOG berukuran 8&#215;8 piksel, 16&#215;16 piksel, atau NxN berapapun N sama saja (2 penjumlahan dan 2 pengurangan). Hal ini akan sangat bermanfaat karena biasanya fitur HOG tidak digunakan dalam satu skala resolusi saja melainkan multi-skala. Implementasi Dalal dan Triggs menggunakan banyak skala sedangkan pengembangan oleh Pedro F. Felzenzswalb yang memenangkan perlombaan PASCAL VOC tahun 2009 menggunakan dua buah skala dan cakupan (root dan kumpulan part).</p>
<p align="justify">langkah selanjutnya adalah memanfaatkan citra HOG integral untuk menghitung fitur HOG.</p>
<p><pre class="brush: python;">def calc_hog_block(hogim, r):
    &quot;&quot;&quot;
    calculate HOG feature given a rectangle and integral HOG image
    
    returns
        HOG feature (not normalized)

    params
        hogim : integral HOG image
        r : 4-tuple representing rect (left,top,right,bottom)
    &quot;&quot;&quot;
    numorient = hogim.shape[2]
    result = np.zeros(numorient)
    for ang in xrange(numorient):
        result[ang] = hogim[r[1],r[0],ang] + hogim[r[3],r[2],ang] - hogim[r[1],r[2],ang] - hogim[r[3],r[0],ang]

    return result
</pre></p>
<p align="justify">Seperti terlihat pada kode di atas, berapapun dimensi area yang akan dihitung fitur HOG lokalnya kompleksitasnya konstan. Hasil histogram di atas tidak dinormalisasi melainkan diserahkan kepada kode yang menggunakan setelahnya. Hal ini disebabkan ada beberapa kombinasi norm yang dapat digunakan untuk menormalisasi vektor/histogram yang dihasilkan dari fungsi di atas.</p>
<p align="justify">Sebagai contoh pemanfaatan fitur HOG agar tulisannya tidak terlalu panjang, saya akan tampilkan bagaimana memvisualisasikan fitur HOG pada setiap area citra. </p>
<p><pre class="brush: python;">def draw_hog(target, ihog, cellsize=8):
    &quot;&quot;&quot;
    visualize HOG features
    
    returns
        None
        
    params
        target  : target image
        ihog    : integral HOG image
        cellsize: size of HOG feature to be visualized (default 8x8)
        
    &quot;&quot;&quot;
    ow,oh = cv.GetSize(target)
    halfcell = cellsize/2
    w,h = ow/cellsize,oh/cellsize
    norient = ihog.shape[2]
    mid = norient/2

    for y in xrange(h-1):
        for x in xrange(w-1):
            px,py=x*cellsize,y*cellsize
            #feat = calc_hog_block(ihog, (px,py,max(px+cellsize, ow-1),max(py+cellsize, oh-1)))
            feat = calc_hog_block(ihog, (px, py, px+cellsize, py+cellsize))
            px += halfcell
            py += halfcell
            
            #L1-norm, nice for visualization
            mag = np.sum(feat)
            maxv = np.max(feat)
            if mag &gt; 1e-3:
                nfeat = feat/maxv
                N = norient
                fdraw = []
                for i in xrange(N):
                    angmax = nfeat.argmax()
                    valmax = nfeat[angmax]
                    x1 = int(round(valmax*halfcell*np.sin((angmax-mid)*np.pi/mid)))
                    y1 = int(round(valmax*halfcell*np.cos((angmax-mid)*np.pi/mid)))
                    gv = int(round(255*feat[angmax]/mag))
                    
                    #don't draw if less than a threshold
                    if gv &lt; 30:
                        break
                    fdraw.insert(0, (x1,y1,gv))
                    nfeat[angmax] = 0.
                    
                #draw from smallest to highest gradient magnitude
                for i in xrange(len(fdraw)):
                    x1,y1,gv = fdraw[i]
                    cv.Line(target, (px-x1,py+y1), (px+x1,py-y1), cv.CV_RGB(gv, gv, gv), 1, 8)
            else:
                #don't draw if there's no reponse
                pass
</pre></p>
<p align="justify">cellsize adalah ukuran dari area yang dihitung untuk mendapatkan HOG lokal. Setiap histogram digambarkan sebagai garis yang orientasinya menyesuaikan. Ada sedikit perbedaan di sini yaitu arah kemiringan garis yang divisualisasikan bukan menggambarkan arah gradien melainkan diputar 90 derajat (tegak lurus) atau normal dari gradien. Hal ini dilakukan untuk memudahkan evaluasi secara visual karena garis yang digambar bersesuaian dengan puncak dari gradien di citra asal.</p>
<p align="justify">Contoh penggunaan fungsi-fungsi dan prosedur di atas ada pada kode berikut.</p>
<p><pre class="brush: python;">im = cv.LoadImage('gambar.jpg')

#image for visualization
vhog = cv.CreateImage(cv.GetSize(im), 8, 1)

hog = calc_hog(im)

draw_hog(vhog, hog, 8)
cv.ShowImage('hi', vhog)

#clear for reuse
cv.Set(vhog, 0)

draw_hog(vhog, hog, 16)
cv.ShowImage('lo', vhog)

key = cv.WaitKey(0)
</pre></p>
<p align="justify">Kekurangan dari kode di atas adalah, untuk menghitung citra HOG diperlukan waktu yang cukup lama yang mungkin disebabkan oleh overhead di python dan numpy. Karena saya masih bereksperimen dan belum berencana membuat aplikasi yang interaktif menggunakan HOG, Hal ini masih ditoleransi. Mungkin saya akan mempertimbangkan untuk menggunakan interface lain untuk memanfaatkan fitur HOG ini (C,C++,atau C#). Contoh hasil penghitungan dan visualisasi fitur HOG dapat dilihat pada gambar-gambar berikut.</p>
<div id="attachment_519" class="wp-caption alignnone" style="width: 310px"><a href="http://pebbie.files.wordpress.com/2011/11/jalan2.jpg"><img src="http://pebbie.files.wordpress.com/2011/11/jalan2.jpg?w=300&#038;h=225" alt="citra asal" title="jalan2" width="300" height="225" class="size-medium wp-image-519" /></a><p class="wp-caption-text">citra asal</p></div>
<div id="attachment_520" class="wp-caption alignnone" style="width: 310px"><a href="http://pebbie.files.wordpress.com/2011/11/jalan2_hog8x8.jpg"><img src="http://pebbie.files.wordpress.com/2011/11/jalan2_hog8x8.jpg?w=300&#038;h=239" alt="" title="jalan2_hog8x8" width="300" height="239" class="size-medium wp-image-520" /></a><p class="wp-caption-text">Tampilan fitur HOG dengan parameter area lokal 8x8 piksel</p></div>
<div id="attachment_521" class="wp-caption alignnone" style="width: 310px"><a href="http://pebbie.files.wordpress.com/2011/11/jalan2_hog4x4.jpg"><img src="http://pebbie.files.wordpress.com/2011/11/jalan2_hog4x4.jpg?w=300&#038;h=239" alt="" title="jalan2_hog4x4" width="300" height="239" class="size-medium wp-image-521" /></a><p class="wp-caption-text">Tampilan fitur HOG dengan parameter area lokal 4x4 piksel</p></div>
<p align="justify">Sampai dengan kondisi di atas, saya masih ragu melakukan klasifikasi (misal mendeteksi objek mobil pada citra di atas) hanya dengan melihat visualisasinya saja tampak kurang diskriminatif. Sepertinya masih perlu dibuktikan apakah bisa melakukan deteksi objek hanya berdasarkan fitur HOG tersebut. Mari kita lanjutkan lain kali saja.</p>
<p><strong>ralat</strong></p>
<ul>
<li>untuk menampilkan gambarnya harusnya cos untuk y dan sin untuk x, dan tanda untuk y dinegasikan, gambar akan diupdate segera.</li>
</ul>
<div id="attachment_534" class="wp-caption alignnone" style="width: 310px"><a href="http://pebbie.files.wordpress.com/2011/11/jalan2_hog8x8r.jpg"><img src="http://pebbie.files.wordpress.com/2011/11/jalan2_hog8x8r.jpg?w=300&#038;h=239" alt="" title="jalan2_hog8x8r" width="300" height="239" class="size-medium wp-image-534" /></a><p class="wp-caption-text">hasil visualisasi HOG 8x8 (yang benar)</p></div>
<div id="attachment_535" class="wp-caption alignnone" style="width: 310px"><a href="http://pebbie.files.wordpress.com/2011/11/jalan2_hog4x4r.jpg"><img src="http://pebbie.files.wordpress.com/2011/11/jalan2_hog4x4r.jpg?w=300&#038;h=239" alt="" title="jalan2_hog4x4r" width="300" height="239" class="size-medium wp-image-535" /></a><p class="wp-caption-text">visualisasi HOG 4x4 (yang benar)</p></div>
<p align="justify">jadi selama ini yang salah itu cara visualisasinya. Kalau begini saya jadi optimis mencoba menerapkan SVM untuk klasifikasi objek (mobil misalny). Mungkin juga mengasosiasikan model bagian dengan segmentation mask untuk digabung dengan grabcut (eh, ngebocorin kerjaan).</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pebbie.wordpress.com/515/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pebbie.wordpress.com/515/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/pebbie.wordpress.com/515/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/pebbie.wordpress.com/515/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/pebbie.wordpress.com/515/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/pebbie.wordpress.com/515/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/pebbie.wordpress.com/515/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/pebbie.wordpress.com/515/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/pebbie.wordpress.com/515/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/pebbie.wordpress.com/515/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/pebbie.wordpress.com/515/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/pebbie.wordpress.com/515/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/pebbie.wordpress.com/515/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/pebbie.wordpress.com/515/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pebbie.wordpress.com&amp;blog=944265&amp;post=515&amp;subd=pebbie&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://pebbie.wordpress.com/2011/11/10/computing-hog-features-in-opencv-python/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b790f5007b6f9383710eceeabe7b9e33?s=96&#38;d=wavatar&#38;r=X" medium="image">
			<media:title type="html">pebbie</media:title>
		</media:content>

		<media:content url="http://pebbie.files.wordpress.com/2011/11/jalan2.jpg?w=300" medium="image">
			<media:title type="html">jalan2</media:title>
		</media:content>

		<media:content url="http://pebbie.files.wordpress.com/2011/11/jalan2_hog8x8.jpg?w=300" medium="image">
			<media:title type="html">jalan2_hog8x8</media:title>
		</media:content>

		<media:content url="http://pebbie.files.wordpress.com/2011/11/jalan2_hog4x4.jpg?w=300" medium="image">
			<media:title type="html">jalan2_hog4x4</media:title>
		</media:content>

		<media:content url="http://pebbie.files.wordpress.com/2011/11/jalan2_hog8x8r.jpg?w=300" medium="image">
			<media:title type="html">jalan2_hog8x8r</media:title>
		</media:content>

		<media:content url="http://pebbie.files.wordpress.com/2011/11/jalan2_hog4x4r.jpg?w=300" medium="image">
			<media:title type="html">jalan2_hog4x4r</media:title>
		</media:content>
	</item>
		<item>
		<title>Eksperimen Markov Random Field untuk Binerisasi Citra</title>
		<link>http://pebbie.wordpress.com/2011/09/20/eksperimen-markov-random-field-untuk-binerisasi-citra/</link>
		<comments>http://pebbie.wordpress.com/2011/09/20/eksperimen-markov-random-field-untuk-binerisasi-citra/#comments</comments>
		<pubDate>Tue, 20 Sep 2011 17:08:14 +0000</pubDate>
		<dc:creator>pebbie</dc:creator>
				<category><![CDATA[delphi]]></category>
		<category><![CDATA[image processing]]></category>
		<category><![CDATA[markov random field]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://pebbie.wordpress.com/?p=503</guid>
		<description><![CDATA[Kemarin saya mencoba mengimplementasi Markov Random Field untuk mempelajari prinsip2 implementasinya. Sebetulnya agak bingung juga untuk membuat implementasinya karena kebanyakan referensi yang membahas topik ini penuh dengan notasi matematik dan istilah-istilah yang buat saya masih asing (mungkin pernah dengar tapi belum terlalu paham). Sampai akhirnya cari-cari dan nemu sampel kode dalam C++ dari situs hackchina. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pebbie.wordpress.com&amp;blog=944265&amp;post=503&amp;subd=pebbie&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p align="justify">Kemarin saya mencoba mengimplementasi <a href="http://en.wikipedia.org/wiki/Markov_Random_Field" target="_blank">Markov Random Field</a> untuk mempelajari prinsip2 implementasinya. Sebetulnya agak bingung juga untuk membuat implementasinya karena kebanyakan referensi yang membahas topik ini penuh dengan notasi matematik dan istilah-istilah yang buat saya masih asing (mungkin pernah dengar tapi belum terlalu paham). Sampai akhirnya cari-cari dan nemu sampel kode dalam C++ dari situs hackchina. Markov Random Field (selanjutnya saya tulis MRF) atau jaringan markov adalah model probabilistik pada struktur graf tak berarah(graphical model). Berbeda dengan jaringan bayes (Bayesian Network) yang diajarkan di kuliah intelejensia buatan yang merupakan model probabilistik pada graf berarah. Prinsip yang digunakan pada MRF adalah optimasi energi. Setelah saya implementasi, saya merasa ada sedikit kemiripan dengan prinsip optimasi probabilistik pada <a href="http://en.wikipedia.org/wiki/Ant_colony_optimization" target="_blank">Ant Colony Optimization</a>.</p>
<p align="justify">Saya menggunakan MRF untuk memodelkan proses binerisasi citra. Masukan proses ini diasumsikan adalah citra <em>grayscale</em>. Memodelkan proses binerisasi citra menggunakan MRF dimulai dengan membuat model energi potensial terhadap <a href="http://en.wikipedia.org/wiki/Clique_(graph_theory)" target="_blank">clique</a> (subgraf yang merupakan graf komplit) pada graf. Citra dianggap sebagai graf berstruktur grid dengan tiap piksel sebagai simpul dan terhubung dengan piksel tetangganya (saya menggunakan ketetanggaan 4 untuk menghubungkan antar piksel). Setiap konfigurasi pelabelan piksel dapat dievaluasi energinya secara keseluruhan sebagai jumlah dari energi pada tiap piksel. Pelabelan/Pewarnaan piksel yang optimal dicapai bila energi yang berasosiasi dengan konfigurasi tersebut adalah minimal terhadap pelabelan lainnya.</p>
<p align="justify">Karena saya sudah akrab dengan model optimasi berbasis populasi seperti algoritma genetik, ant colony, atau particle swarm saya tadinya berniat mencari konfigurasi pelabelan dengan menggunakan teknik ini. Niat ini kemudian saya urungkan karena malas membayangkan memori dan waktu yang diperlukan untuk mencari konfigurasi yang optimal (kalau N adalah besar populasi, maka perlu N citra tambahan untuk algoritma genetik dan 2N untuk PSO). Akhirnya dengan berat hati saya paksakan diri untuk mempelajari teknik optimasi dengan menggunakan Gibbs sampler.</p>
<p> <span id="more-503"></span></p>
<p align="justify">Energi ini bisa dianalogikan sebagai risiko untuk menggunakan pelabelan yang dipilih. Saya menggunakan pairwise clique (subgraf yang terdiri dari 2 simpul) sebagai orde tertinggi untuk memodelkan energi potensial. Energi potensial pada tiap piksel adalah risiko nilai suatu piksel dibandingkan dengan &#8216;ground truth&#8217; prior. &#8216;ground truth&#8217; ini saya modelkan secara sederhana seperti thresholding menggunakan nilai mutlak 128. Energi potensial pada pasangan piksel merupakan <em>smoothness prior</em> yaitu estimasi risiko jika pelabelan suatu piksel terhadap tetangganya. secara keseluruhan, proses binerisasi ini mirip dengan proses binerisasi yang deterministik yang dilanjutkan dengan penghalusan.</p>
<p align="justify">Kode berikut adalah potongan prosedur yang saya buat di delphi. Beberapa bagian saya buang seperti misalnya pemodelan temperatur untuk proses sampling dan pembatasan pengulangan. Model Prior juga saya ganti dari yang berbasis statistik tiap label menjadi nilai mutlak.</p>
<p><pre class="brush: delphi;">
procedure TForm1.do_mrf;
const N4            : array[0..3] of TPoint = ((X: - 1; Y: 0), (X: 1; Y: 0), (X: 0; Y: - 1), (X: 0; Y: 1));
const NLABEL        = 2;

var
  bi, bo            : TBitmap;
  i, j, k           : integer;
  p1, po            : array of PArrRGB;
  lf                : array of array of 0..NLABEL - 1; //labeling configuration
  cur_energy, z, r  : real;
  delta             : real;
  prev_energy, total_energy: real;
  step, max_step    : integer;
  Energy            : array[0..NLABEL - 1] of real;

  function Vc1(x, y, l: integer): real;
  {
    risiko jika label suatu pixel berbeda dari prior
  }
  begin
    result := abs(l * 255 - p1[y][x].r);//prior kecenderungan absolut
  end;

  function Vc2(x, y, l: integer): real;
  {
    risiko kalau suatu pixel diberi label berbeda dengan label tetangganya (pairwise clique)
  }
  var
    n               : integer;
    dl, dx          : real;
  begin
    result := 0;
    for n := 0 to 3 do begin
      dl := abs(lf[y + N4[n].Y][x + N4[n].X] - l);
      dx := abs(p1[y + N4[n].Y][x + N4[n].X].r - p1[y][x].r);
      result := result + dl * dx;
    end;
  end;

  function Vc(x, y, l: integer): real;
  {
    total risiko suatu pixel (x,y) diberi label l
  }
  begin
    result := Vc1(x, y, l) + Vc2(x, y, l);
  end;

  function calc_energy: real;
  {
    total risiko pelabelan seluruh piksel
  }
  var i, j          : integer;
  begin
    result := 0.0;
    for j := 1 to bo.Height - 2 do
      for i := 1 to bo.Width - 2 do
        result := result + Vc(i, j, lf[j][i]);
    result := result / (bo.Width * bo.Height);
  end;

  procedure initialize;
  {
    inisialisasi dengan nilai prior
  }
  var
    i, j, k         : integer;
    min_v, v        : real;
  begin
    for j := 1 to bo.Height - 2 do begin
      for i := 1 to bo.Width - 2 do begin

        min_v := MAXINT;
        for k := 0 to NLABEL - 1 do begin
          v := Vc1(i, j, k);
          if v &lt; min_v then begin
            min_v := v;
            lf[j][i] := k;
          end;
        end;

      end;
    end;
  end;

  procedure display_output;
  var
    j, i, tmp       : integer;
  begin
    for j := 0 to bo.Height - 1 do begin
      for i := 0 to bo.Width - 1 do begin
        if lf[j][i] = 1 then tmp := 255 else tmp := 0;
        po[j][i] := warna_create(tmp, tmp, tmp);
      end;
    end;
    Image1.Picture.Bitmap.Assign(bo);
    Image1.Refresh;
  end;

begin
  //bi := citra_filter_mean(Image1.Picture.Bitmap, KMEAN);//pakai ini untuk kasus denoising citra biner
  bi := citra_make_greyscale(image1.picture.bitmap);
  bo := citra_clone(bi);

  setlength(p1, bi.Height);
  setlength(po, bo.Height);
  for j := 0 to bi.Height - 1 do p1[j] := bi.ScanLine[j];
  for j := 0 to bo.Height - 1 do po[j] := bo.ScanLine[j];

  setlength(lf, bo.Height);
  for j := 0 to bo.Height - 1 do setlength(lf[j], bo.Width);

  step := 0;
  max_step := 50;

  initialize;
  prev_energy := calc_energy;
  display_output;

  repeat
    //gibbs sampling on every site
    for j := 1 to bo.Height - 2 do begin
      for i := 1 to bo.Width - 2 do begin

        total_energy := 0;
        for k := 0 to NLABEL - 1 do begin
          Energy[k] := exp(-Vc(i, j, k));
          total_energy := total_energy + Energy[k];
        end;
        r := random;
        z := 0;
        for k := 0 to NLABEL - 1 do begin
          try
          z := z + Energy[k] / total_energy;
          except
            showmessage(format('TotalE=%f',[total_energy]));
          end;
          if z &gt; r then begin
            lf[j][i] := k;
            break;
          end;
        end;

      end;
    end;
    
    display_output;

    cur_energy := calc_energy;
    delta := cur_energy - prev_energy;
    Caption := format('#%d E=%.5f', [step, delta]);
    prev_energy := cur_energy;

    inc(step);
  until (abs(delta) &lt; 1e-3) or (step &gt;= max_step);
  
  setlength(p1, 0);
  setlength(po, 0);
  for j := 0 to bo.Height-1 do setlength(lf[j], 0);
  setlength(lf, 0);
  bo.Free;
  bi.Free;
end;
</pre></p>
<p>Hasilnya bisa dilihat pada gambar berikut :<br />
<div id="attachment_505" class="wp-caption alignnone" style="width: 266px"><a href="http://pebbie.files.wordpress.com/2011/09/mpf_sol3_lander.jpg"><img src="http://pebbie.files.wordpress.com/2011/09/mpf_sol3_lander.jpg?w=500" alt="" title="citra asal"   class="size-full wp-image-505" /></a><p class="wp-caption-text">citra asal</p></div><br />
<div id="attachment_506" class="wp-caption alignnone" style="width: 266px"><a href="http://pebbie.files.wordpress.com/2011/09/mpf_sol3_lander_thr.jpg"><img src="http://pebbie.files.wordpress.com/2011/09/mpf_sol3_lander_thr.jpg?w=500" alt="" title="citra biner menggunakan global threshold"   class="size-full wp-image-506" /></a><p class="wp-caption-text">citra biner menggunakan global threshold</p></div><br />
<div id="attachment_507" class="wp-caption alignnone" style="width: 266px"><a href="http://pebbie.files.wordpress.com/2011/09/mpf_sol3_lander_mrf.jpg"><img src="http://pebbie.files.wordpress.com/2011/09/mpf_sol3_lander_mrf.jpg?w=500" alt="" title="citra biner menggunakan MRF"   class="size-full wp-image-507" /></a><p class="wp-caption-text">citra biner menggunakan MRF</p></div><br />
<div id="attachment_508" class="wp-caption alignnone" style="width: 266px"><a href="http://pebbie.files.wordpress.com/2011/09/mpf_sol3_lander_dif.jpg"><img src="http://pebbie.files.wordpress.com/2011/09/mpf_sol3_lander_dif.jpg?w=500" alt="" title="beda hasil threshold manual dengan MRF"   class="size-full wp-image-508" /></a><p class="wp-caption-text">beda hasil threshold manual dengan MRF</p></div></p>
<p align="justify">Model MRF di atas (khususnya bagian prior 1-clique) tidak efektif untuk citra yang tidak terlalu kontras (misal citra teks yang pencahayaannya kurang bagus) atau pembersihan citra biner yang ber-noise seperti pada contoh berikut.</p>
<div id="attachment_509" class="wp-caption alignnone" style="width: 310px"><a href="http://pebbie.files.wordpress.com/2011/09/noisy.png"><img src="http://pebbie.files.wordpress.com/2011/09/noisy.png?w=300&#038;h=225" alt="" title="noisy" width="300" height="225" class="size-medium wp-image-509" /></a><p class="wp-caption-text">noisy</p></div>
<p>jika menggunakan model MRF seperti kode di atas hasilnya akan seperti ini.</p>
<div id="attachment_510" class="wp-caption alignnone" style="width: 310px"><a href="http://pebbie.files.wordpress.com/2011/09/noisy_mrf1.png"><img src="http://pebbie.files.wordpress.com/2011/09/noisy_mrf1.png?w=300&#038;h=225" alt="" title="noisy_mrf1" width="300" height="225" class="size-medium wp-image-510" /></a><p class="wp-caption-text">noisy_mrf1</p></div>
<p>Untuk mengatasi kasus seperti itu, saya mencoba melakukan smoothing citra awal yang sudah biner menjadi grayscale menggunakan mean filter. sehingga hasil akhirnya menjadi seperti ini (cukup memuaskan). </p>
<div id="attachment_511" class="wp-caption alignnone" style="width: 310px"><a href="http://pebbie.files.wordpress.com/2011/09/noisy_mrf.png"><img src="http://pebbie.files.wordpress.com/2011/09/noisy_mrf.png?w=300&#038;h=225" alt="" title="noisy_mrf" width="300" height="225" class="size-medium wp-image-511" /></a><p class="wp-caption-text">noisy_mrf</p></div>
<p align="justify">MRF juga dapat diterapkan pada graf penalaran First-Order Logic (FOL) yang diberi atribut probabilitas pada tiap term-nya. Kombinasi FOL dengan MRF disebut juga sebagai Markov-Logic Network (MLN). Pada kasus MLN pelabelan dilakukan pada unifikasi term dan busur graf dimodelkan sebagai ketergantugan antar instansiasi dari term. MLN ini saya gunakan dalam riset untuk membaca tulisan tangan (handwriting recognition) sebagai mesin inferensi dengan memanfaatkan relasi spasial antar objek (region/titik kontur). Mudah-mudahan bisa diselesaikan segera supaya bisa saya bagikan di blog ini. <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  </p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pebbie.wordpress.com/503/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pebbie.wordpress.com/503/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/pebbie.wordpress.com/503/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/pebbie.wordpress.com/503/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/pebbie.wordpress.com/503/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/pebbie.wordpress.com/503/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/pebbie.wordpress.com/503/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/pebbie.wordpress.com/503/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/pebbie.wordpress.com/503/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/pebbie.wordpress.com/503/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/pebbie.wordpress.com/503/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/pebbie.wordpress.com/503/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/pebbie.wordpress.com/503/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/pebbie.wordpress.com/503/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pebbie.wordpress.com&amp;blog=944265&amp;post=503&amp;subd=pebbie&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://pebbie.wordpress.com/2011/09/20/eksperimen-markov-random-field-untuk-binerisasi-citra/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b790f5007b6f9383710eceeabe7b9e33?s=96&#38;d=wavatar&#38;r=X" medium="image">
			<media:title type="html">pebbie</media:title>
		</media:content>

		<media:content url="http://pebbie.files.wordpress.com/2011/09/mpf_sol3_lander.jpg" medium="image">
			<media:title type="html">citra asal</media:title>
		</media:content>

		<media:content url="http://pebbie.files.wordpress.com/2011/09/mpf_sol3_lander_thr.jpg" medium="image">
			<media:title type="html">citra biner menggunakan global threshold</media:title>
		</media:content>

		<media:content url="http://pebbie.files.wordpress.com/2011/09/mpf_sol3_lander_mrf.jpg" medium="image">
			<media:title type="html">citra biner menggunakan MRF</media:title>
		</media:content>

		<media:content url="http://pebbie.files.wordpress.com/2011/09/mpf_sol3_lander_dif.jpg" medium="image">
			<media:title type="html">beda hasil threshold manual dengan MRF</media:title>
		</media:content>

		<media:content url="http://pebbie.files.wordpress.com/2011/09/noisy.png?w=300" medium="image">
			<media:title type="html">noisy</media:title>
		</media:content>

		<media:content url="http://pebbie.files.wordpress.com/2011/09/noisy_mrf1.png?w=300" medium="image">
			<media:title type="html">noisy_mrf1</media:title>
		</media:content>

		<media:content url="http://pebbie.files.wordpress.com/2011/09/noisy_mrf.png?w=300" medium="image">
			<media:title type="html">noisy_mrf</media:title>
		</media:content>
	</item>
		<item>
		<title>Mengapa Judul Tabel ada di atas dan Judul Gambar ada di bawah?</title>
		<link>http://pebbie.wordpress.com/2011/08/05/mengapa-judul-tabel-ada-di-atas-dan-judul-gambar-ada-di-bawah/</link>
		<comments>http://pebbie.wordpress.com/2011/08/05/mengapa-judul-tabel-ada-di-atas-dan-judul-gambar-ada-di-bawah/#comments</comments>
		<pubDate>Fri, 05 Aug 2011 15:50:18 +0000</pubDate>
		<dc:creator>pebbie</dc:creator>
				<category><![CDATA[akademik]]></category>
		<category><![CDATA[opini]]></category>
		<category><![CDATA[infoviz]]></category>
		<category><![CDATA[visualization]]></category>

		<guid isPermaLink="false">http://pebbie.wordpress.com/?p=499</guid>
		<description><![CDATA[&#8211;intermezzo&#8211;setelah lama tidak menulis dengan alasan tidak sempat, kali ini saya coba menulis walau mungkin isinya tidak seperti biasanya (bedah algoritma). Tulisan ini sekadar membuat interpretasi terhadap aturan penulisan yang biasanya dibuat dalam tulisan ilmiah seperti skripsi/laporan tugas akhir, tesis, dan disertasi. Pertanyaan yang menjadi judul di atas mungkin terinterpretasi sebagai pembenaran terhadap kaidah penulisan. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pebbie.wordpress.com&amp;blog=944265&amp;post=499&amp;subd=pebbie&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p align="justify">&#8211;intermezzo&#8211;setelah lama tidak menulis dengan alasan tidak sempat, kali ini saya coba menulis walau mungkin isinya tidak seperti biasanya (bedah algoritma). Tulisan ini sekadar membuat interpretasi terhadap aturan penulisan yang biasanya dibuat dalam tulisan ilmiah seperti skripsi/laporan tugas akhir, tesis, dan disertasi. Pertanyaan yang menjadi judul di atas mungkin terinterpretasi sebagai pembenaran terhadap kaidah penulisan. oleh sebab itu yang saya tuliskan dalam tulisan ini hanya sebatas opini saja.</p>
<p align="justify">Hal yang menjadi kunci dari pertanyaan di atas adalah interpretasi terhadap susunan informasi. Tabel merupakan kumpulan informasi yang posisinya diatur untuk mempermudah pencarian. oleh sebab itu judul tabel ditempatkan sebelum tabel tersebut (di atas) sebagai petunjuk isi tabel sebelum dilakukan pencarian. Hal ini juga yang menjadi alasan mengapa kepala tabel (<em>table header</em>) ditempatkan di baris pertama atau kolom pertama (kiri atau kanan tergantung kebiasaan baca/tulis).</p>
<p align="justify">Berbeda dengan tabel, judul untuk gambar ditempatkan setelah gambar tersebut (di bawah). Alasannya adalah gambar digunakan untuk mengkomunikasikan pesan (ingat ungkapan &#8216;a picture is worth a thousand worth&#8217;) secara visual. Mata manusia merupakan salah satu indera yang dapat memproses informasi secara paralel. Oleh sebab itu gambar akan diproses terlebih dahulu secara <em>top-down</em> (keseluruhan-detil) dan judul digunakan sebagai pengarah pengambilan kesimpulan terhadap gambar yang sebelumnya dilihat.</p>
<p align="justify">Tabel berisi informasi tekstual yang harus diinterpretasi secara <em>bottom-up</em> karena makna tulisan &#8217;100&#8242; tidak bisa diinterpretasi secara visual secara sekilas (<em>gist</em>) melainkan harus diinterpretasi simbol-per-simbol dan diintegrasi dengan pengetahuan tentang aturan penulisan bilangan desimal. Inilah yang membuat orang pada umumnya cenderung malas untuk membaca tabel dibandingkan melihat representasi lain dari tabel tersebut (grafik) karena beban kerja kognitif (mengolah informasi abstrak) otak lebih banyak digunakan dibanding kerja intuitif (mengolah informasi alamiah) ketika melihat gambar.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pebbie.wordpress.com/499/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pebbie.wordpress.com/499/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/pebbie.wordpress.com/499/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/pebbie.wordpress.com/499/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/pebbie.wordpress.com/499/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/pebbie.wordpress.com/499/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/pebbie.wordpress.com/499/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/pebbie.wordpress.com/499/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/pebbie.wordpress.com/499/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/pebbie.wordpress.com/499/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/pebbie.wordpress.com/499/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/pebbie.wordpress.com/499/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/pebbie.wordpress.com/499/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/pebbie.wordpress.com/499/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pebbie.wordpress.com&amp;blog=944265&amp;post=499&amp;subd=pebbie&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://pebbie.wordpress.com/2011/08/05/mengapa-judul-tabel-ada-di-atas-dan-judul-gambar-ada-di-bawah/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b790f5007b6f9383710eceeabe7b9e33?s=96&#38;d=wavatar&#38;r=X" medium="image">
			<media:title type="html">pebbie</media:title>
		</media:content>
	</item>
		<item>
		<title>Mean Shift Filtering</title>
		<link>http://pebbie.wordpress.com/2011/06/12/mean-shift-filtering/</link>
		<comments>http://pebbie.wordpress.com/2011/06/12/mean-shift-filtering/#comments</comments>
		<pubDate>Sun, 12 Jun 2011 05:37:38 +0000</pubDate>
		<dc:creator>pebbie</dc:creator>
				<category><![CDATA[delphi]]></category>
		<category><![CDATA[image processing]]></category>

		<guid isPermaLink="false">http://pebbie.wordpress.com/?p=484</guid>
		<description><![CDATA[Saya pernah menulis tentang Mean filter, lalu dilanjutkan dengan Bilateral Filter [1]. Kedua filter ini merupakan batu loncatan untuk memahami Mean Shift Filter. Kalau di Mean filter yang dipertimbangkan adalah seluruh piksel yang berada dalam suatu area ketetanggaan maka di Bilateral filter yang dipertimbangkan diseleksi lagi menjadi nilai piksel yang &#8216;berdekatan&#8217; di ruang fitur (feature [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pebbie.wordpress.com&amp;blog=944265&amp;post=484&amp;subd=pebbie&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Saya pernah menulis tentang <a href="http://pebbie.wordpress.com/2007/04/05/jurus-jurus-penghalusan-citra-jurus-1-rata-rata-tetangga/">Mean filter</a>, lalu dilanjutkan dengan <a href="http://pebbie.wordpress.com/2008/06/25/implementasi-bilateral-filtering-di-delphi/">Bilateral Filter</a> <a href="http://en.wikipedia.org/wiki/Bilateral_filter">[1]</a>. Kedua filter ini merupakan batu loncatan untuk memahami <a href="http://en.wikipedia.org/wiki/Mean-shift">Mean Shift Filter</a>. Kalau di Mean filter yang dipertimbangkan adalah <strong>seluruh</strong> piksel yang berada dalam suatu area ketetanggaan maka di Bilateral filter yang dipertimbangkan diseleksi lagi menjadi nilai piksel yang &#8216;berdekatan&#8217; di ruang fitur (<em>feature space</em>) dengan piksel yang menjadi acuan (biasanya di tengah). Kriteria untuk menentukan suatu nilai &#8216;berdekatan&#8217; bisa jadi berupa nilai keabuan (<em>grayscale</em>), jarak antara warna menggunakan <em>metric euclid</em>(atau <em>metric</em> lain seperti <em>manhattan block distance</em>) pada satu ruang warna (RGB, YUV, YCbCr, dll). </p>
<p>Untuk memahami mean-shift filter, perlu menambahkan konsep bahwa nilai rata-rata yang dipakai bisa jadi tidak terbatas di area ketetanggaan itu saja melainkan bisa saja ada di tempat lain. Oleh sebab itu, nilai rata-ratanya perlu &#8216;jalan-jalan&#8217; atau bergeser (<em>shift</em>) sampai menemukan nilai rata-rata yang tepat. Kalau dalam mean filter dan bilateral filter yang dihitung hanya rata-rata nilai piksel, maka pada mean-shift filter koordinat piksel yang masuk kriteria seleksi juga dihitung nilai rata-ratanya. Dengan demikian didapat nilai rata-rata koordinat piksel sebagai koordinat baru. Nilai koordinat baru ini kemudian dijadikan titik acuan untuk menghitung nilai rata-rata di ruang fitur (intensitas piksel, warna, atau gradien). Jika titik koordinat baru ternyata tidak berubah maka nilai rata-rata di ruang fitur piksel digunakan untuk mengganti nilai piksel di seluruh koordinat yang pernah menjadi koordinat acuan sampai di koordinat semula.<br />
<span id="more-484"></span><br />
Berbasis kode mean-shift filter di <a href="http://rsb.info.nih.gov/ij/plugins/mean-shift.html">plugin ImageJ</a>, saya buat versi delphi untuk mean-shift filtering. Kode aslinya dimodifikasi supaya lebih efisien dengan mengasumsikan koordinat yang pernah dikunjungi diganti dengan nilai akhir maka koordinat yang pernah dikunjungi tidak perlu lagi diproses. Efisiensi dilakukan dengan menggunakan citra biner yang berfungsi sebagai <em>mask</em> atau <em>flag</em>, yaitu penanda suatu piksel sudah pernah diproses (akibat penggeseran atau belum). </p>
<p><pre class="brush: delphi;">procedure TForm1.MeanShift1Click(Sender: TObject);
var
  rad               : array of TPoint;
  i, j, k           : integer;
  FeatureSpaceRadius: real;
  ImageSpaceRadius  : Integer;
  fsr2, isr2        : real;
  yiqimage          : array of array of array of real;
  p                 : array of PArrRGB;//lihat tulisan sebelumnya tentang mengakses piksel
  b                 : TBitmap;
  delta             : real;
  iter, maxiter     : integer;
  cur, old          : TPoint;
  sumx, sumy, sumf1, sumf2, sumf3: real;
  invnum            : real;
  xx, yy            : integer;
  f1, f2, f3        : real;
  of1, of2, of3     : real;
  df1, df2, df3     : real;
  dx, dy            : integer;
  bs                : TBitmap;
  mask              : array of array of boolean;
  path              : array of TPoint;

  function is_ok(x, y: integer): boolean;
  begin
    result := (x &gt;= 0) and (y &gt;= 0) and (x &lt; b.Width) and (y &lt; b.Height);
  end;
begin
  //transform image to feature space (YIQ color space)
  b := Image1.Picture.Bitmap;
  setlength(yiqimage, b.Height);
  setlength(mask, b.Height);
  setlength(p, b.Height);
  for j := 0 to high(yiqimage) do begin
    p[j] := b.ScanLine[j];
    setlength(yiqimage[j], b.Width);
    setlength(mask[j], b.Width);
    for i := 0 to b.Width - 1 do with p[j][i] do begin
        mask[j][i] := True;
        setlength(yiqimage[j][i], 3);
        yiqimage[j][i][0] := 0.299 * r + 0.587 * g + 0.114 * b; ;
        yiqimage[j][i][1] := 0.5957 * r - 0.2744 * g - 0.3212 * b; ;
        yiqimage[j][i][2] := 0.2114 * r - 0.5226 * g + 0.3111 * b;
      end;
  end;

  //precompute sampling displacement
  ImageSpaceRadius := 20;
  isr2 := ImageSpaceRadius * ImageSpaceRadius;
  for j := -ImageSpaceRadius to ImageSpaceRadius do begin
    for i := -ImageSpaceRadius to ImageSpaceRadius do begin
      if i * i + j * j &lt;= isr2 then begin
        SetLength(rad, length(rad) + 1);
        rad[high(rad)] := Point(i, j);
      end;
    end;
  end;

  FeatureSpaceRadius := 40;
  fsr2 := FeatureSpaceRadius * FeatureSpaceRadius;
  maxiter := 100;
  for j := 0 to b.Height - 1 do begin
    for i := 0 to b.Width - 1 do begin
      if not mask[j][i] then continue;
      cur.X := i;
      cur.Y := j;
      iter := 0;
      f1 := yiqimage[j][i][0];
      f2 := yiqimage[j][i][1];
      f3 := yiqimage[j][i][2];
      setlength(path, 0);
      repeat
        old := cur;
        of1 := f1;
        of2 := f2;
        of3 := f3;

        invnum := 0;
        sumx := 0;
        sumy := 0;
        sumf1 := 0;
        sumf2 := 0;
        sumf3 := 0;
        for k := 0 to high(rad) do begin
          xx := cur.X + rad[k].X;
          yy := cur.Y + rad[k].Y;
          if is_ok(xx, yy) then begin
            df1 := f1 - yiqimage[yy][xx][0];
            df2 := f2 - yiqimage[yy][xx][1];
            df3 := f3 - yiqimage[yy][xx][2];
            if (df1 * df1 + df2 * df2 + df3 * df3 &lt;= FSR2) then begin
              invnum := invnum + 1;
              sumx := sumx + xx;
              sumy := sumy + yy;
              sumf1 := sumf1 + yiqimage[yy][xx][0];
              sumf2 := sumf2 + yiqimage[yy][xx][1];
              sumf3 := sumf3 + yiqimage[yy][xx][2];
            end;
          end;
        end;
        if invnum &lt; 1 then begin
          break;
        end;
        invnum := 1.0 / invnum;
        f1 := sumf1 * invnum;
        f2 := sumf2 * invnum;
        f3 := sumf3 * invnum;
        cur.X := round(sumx * invnum);
        cur.Y := round(sumy * invnum);
        if not mask[cur.Y][cur.X] then begin
          break;
        end;
        setlength(path, length(path) + 1);
        path[high(path)] := cur;
        dx := cur.X - old.X;
        dy := cur.Y - old.Y;
        df1 := f1 - of1;
        df2 := f2 - of2;
        df3 := f3 - of3;
        delta := dx * dx + dy * dy + df1 * df1 + df2 * df2 + df3 * df3;
        inc(iter);
      until (delta &lt; 3) or (iter &gt;= maxiter);
      p[j][i].r := round(f1 + 0.9563 * f2 + 0.6210 * f3);
      p[j][i].g := round(f1 - 0.2721 * f2 - 0.6473 * f3);
      p[j][i].b := round(f1 - 1.1070 * f2 + 1.7046 * f3);
      mask[j][i] := false;
      for k := 0 to high(path) do begin
        mask[j][i] := false;
        p[path[k].Y][path[k].X] := p[j][i];
      end;
    end;
  end;
  Image1.Refresh;
end;</pre></p>
<p>Kode di atas menggunakan ruang warna <a href="http://en.wikipedia.org/wiki/YIQ">YIQ</a> untuk menghitung kedekatan antar piksel. Fungsi jarak yang digunakan adalah jarak Euclid. Selain fungsi jarak dan ruang fitur, filter mean-shift memiliki 2 parameter umum yaitu Radius dalam domain spasial (ImageSpaceRadius) yang dalam filter-filter umumnya menunjuk ke area ketetanggaan dan Radius dalam domain fitur (FeatureSpaceRadius) yaitu batas kedekatan suatu piksel pada ruang fitur. Contoh pemrosesan dengan filter mean-shift ditampilkan di gambar berikut.</p>
<p><a href="http://pebbie.files.wordpress.com/2011/06/d_765_cm.jpg"><img src="http://pebbie.files.wordpress.com/2011/06/d_765_cm.jpg?w=300&#038;h=225" alt="" title="citra asal" width="300" height="225" class="alignnone size-medium wp-image-486" /></a></p>
<p><a href="http://pebbie.files.wordpress.com/2011/06/meanshift.png"><img src="http://pebbie.files.wordpress.com/2011/06/meanshift.png?w=300&#038;h=224" alt="" title="output meanshift" width="300" height="224" class="alignnone size-medium wp-image-485" /></a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pebbie.wordpress.com/484/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pebbie.wordpress.com/484/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/pebbie.wordpress.com/484/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/pebbie.wordpress.com/484/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/pebbie.wordpress.com/484/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/pebbie.wordpress.com/484/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/pebbie.wordpress.com/484/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/pebbie.wordpress.com/484/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/pebbie.wordpress.com/484/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/pebbie.wordpress.com/484/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/pebbie.wordpress.com/484/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/pebbie.wordpress.com/484/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/pebbie.wordpress.com/484/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/pebbie.wordpress.com/484/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pebbie.wordpress.com&amp;blog=944265&amp;post=484&amp;subd=pebbie&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://pebbie.wordpress.com/2011/06/12/mean-shift-filtering/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b790f5007b6f9383710eceeabe7b9e33?s=96&#38;d=wavatar&#38;r=X" medium="image">
			<media:title type="html">pebbie</media:title>
		</media:content>

		<media:content url="http://pebbie.files.wordpress.com/2011/06/d_765_cm.jpg?w=300" medium="image">
			<media:title type="html">citra asal</media:title>
		</media:content>

		<media:content url="http://pebbie.files.wordpress.com/2011/06/meanshift.png?w=300" medium="image">
			<media:title type="html">output meanshift</media:title>
		</media:content>
	</item>
		<item>
		<title>Generating Python Code for Matrix Inner Product in SQLite Database</title>
		<link>http://pebbie.wordpress.com/2011/02/10/generating-python-code-for-matrix-inner-product-in-sqlite-database/</link>
		<comments>http://pebbie.wordpress.com/2011/02/10/generating-python-code-for-matrix-inner-product-in-sqlite-database/#comments</comments>
		<pubDate>Thu, 10 Feb 2011 09:19:19 +0000</pubDate>
		<dc:creator>pebbie</dc:creator>
				<category><![CDATA[computer vision]]></category>
		<category><![CDATA[mathematics]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[code generation]]></category>
		<category><![CDATA[image retrieval]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://pebbie.wordpress.com/?p=476</guid>
		<description><![CDATA[Pada waktu event wordcampid yang lalu saya sempat menulis kode untuk melakukan pencarian citra dari database (image retrieval). Kodenya ditulis ketika agak senggang atau ketika topik pembicaraannya tidak terlalu menarik. Saya menggunakan fitur berupa matriks 8&#215;8 yang disimpan dalam database SQLite. Pada intinya saya berniat melakukan inner (dot) product melalui pernyataan SQL (supaya sekalian diurutin [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pebbie.wordpress.com&amp;blog=944265&amp;post=476&amp;subd=pebbie&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Pada waktu event wordcampid yang lalu saya sempat menulis kode untuk melakukan pencarian citra dari database (image retrieval). Kodenya ditulis ketika agak senggang atau ketika topik pembicaraannya tidak terlalu menarik. Saya menggunakan fitur berupa matriks 8&#215;8 yang disimpan dalam database SQLite. Pada intinya saya berniat melakukan inner (dot) product melalui pernyataan SQL (supaya sekalian diurutin dan dibatasi top N <img src='http://s0.wp.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' />  ). Awalnya senang-senang saja, lama-lama saya bosan juga kalau harus mengetik 64 field dan 64 parameter untuk setiap fungsi (ada 3 fungsi yaitu mendefinisikan <em>table</em>, <em>insert</em>, dan <em>find</em>). jadi totalnya 64 x 5 = 320 field harus saya ketik manual. Saya tidak pakai perulangan karena malas melihat kode berisi penempelan string kala itu. Hari berikutnya akhirnya saya menulis kode untuk mengotomatisasi pekerjaan tersebut (bayangkan kalau saya ubah eksperimennya jadi fitur berukuran 12&#215;12 atau 25&#215;25). </p>
<p>Kode yang saya tulis ketika dijalankan akan menghasilkan file teks berisi kode python yang spesifik dengan dimensi matriks yang menjadi parameter.<br />
<span id="more-476"></span><br />
<pre class="brush: python;">def genmat(la):
    result = []
    for i in xrange(0,la[0]):
        if len(la)==1:
            result += [[&quot;%s&quot; % i]]
        else:
            row = [&quot;%s&quot; % i]
            tmp = genmat(la[1:])
            for x in tmp:
                result += [row+x]
    return result

def setup(n, output=&quot;Test&quot;, tablename=&quot;vec&quot;, cols=[], classprefix=&quot;DocSearch&quot;):
    classname=classprefix+output
    fpy = open(output+&quot;.py&quot;, &quot;w&quot;)
    if len(cols)==0:
        cols = [(&quot;id&quot;, &quot;INTEGER PRIMARY KEY&quot;), (&quot;desc&quot;, &quot;CHAR(255)&quot;)]
    lcols = []
    try:
        dim = len(n)
        vcols = genmat(n)
    except:
        dim = 1
        vcols = genmat([n])
    for f in vcols:
        lcols += [(&quot;v&quot;+&quot;_&quot;.join(f), &quot;DOUBLE NOT NULL&quot;)]
    scols = &quot;, &quot;.join([&quot;%s %s&quot; % (c, t) for c, t in lcols+cols])
    fpy.write(&quot;&quot;&quot;
import sqlite3

class %s:
    def __init__(self, dbname=&quot;db%s.db&quot;):
        self.db = dbname
        self.con = sqlite3.connect(self.db)
        
    def setup(self):
        self.con.execute(&quot;CREATE TABLE %s (%s)&quot;)
        self.con.commit()
    &quot;&quot;&quot; % (classname, output, tablename, scols))

    acols = &quot;, &quot;.join([&quot;%s&quot; % (c) for c, t in cols])
    icols = &quot;, &quot;.join([&quot;%s&quot; % (c) for c, t in lcols+cols])
    ivcols = &quot;, &quot;.join([&quot;?&quot;]*(len(lcols)+len(cols)))
    _ipcols = []
    for f in vcols:
        _ipcols += [&quot;f&quot;+&quot;&quot;.join([&quot;[&quot;+v+&quot;]&quot; for v in f])]
    ipcols = &quot;, &quot;.join(_ipcols)
    fpy.write(&quot;&quot;&quot;    
    def insert(self, f, %s):
        self.con.execute(&quot;INSERT INTO %s (%s) VALUES (%s)&quot; %s (%s, %s))
        self.con.commit()
    &quot;&quot;&quot; % (acols, tablename, icols, ivcols, &quot;%&quot;, ipcols, acols))
    
    qcols = &quot;, &quot;.join([&quot;%s*%s&quot; % (c, &quot;?&quot;) for c, t in lcols])
    fpy.write(&quot;&quot;&quot;    
    def query(self, f):
        c = self.con.cursor()
        c.execute(&quot;SELECT (%s) as dot, %s FROM %s ORDER BY dot DESC&quot; %s (%s))
        rows = c.fetchall()
        return rows
    &quot;&quot;&quot; % (qcols, acols, tablename, &quot;%&quot;, ipcols))
    
    fpy.write(&quot;&quot;&quot;

if __name__==&quot;__main__&quot;:
    search = %s()
    search.setup()
    &quot;&quot;&quot; % (classname))
    fpy.close()
   
if __name__==&quot;__main__&quot;:
    setup(3, &quot;1x3&quot;)
    setup([2,2], &quot;2x2&quot;)
    setup([8,8], &quot;8x8&quot;)
    #print genmat([2,2])
    </pre> </p>
<p>Kode di atas juga berisi contoh penggunaan fungsi untuk berbagai dimensi (misal 1xn, mxn, mxnxsxtx&#8230;xz). Contoh keluaran untuk matriks 2&#215;2 seperti berikut:</p>
<p><pre class="brush: python;">
import sqlite3

class DocSearch2x2:
    def __init__(self, dbname=&quot;db2x2.db&quot;):
        self.db = dbname
        self.con = sqlite3.connect(self.db)
        
    def setup(self):
        self.con.execute(&quot;CREATE TABLE vec (v0_0 DOUBLE NOT NULL, v0_1 DOUBLE NOT NULL, v1_0 DOUBLE NOT NULL, v1_1 DOUBLE NOT NULL, id INTEGER PRIMARY KEY, desc CHAR(255))&quot;)
        self.con.commit()
        
    def insert(self, f, id, desc):
        self.con.execute(&quot;INSERT INTO vec (v0_0, v0_1, v1_0, v1_1, id, desc) VALUES (?, ?, ?, ?, ?, ?)&quot; % (f[0][0], f[0][1], f[1][0], f[1][1], id, desc))
        self.con.commit()
        
    def query(self, f):
        c = self.con.cursor()
        c.execute(&quot;SELECT (v0_0*?, v0_1*?, v1_0*?, v1_1*?) as dot, id, desc FROM vec ORDER BY dot DESC&quot; % (f[0][0], f[0][1], f[1][0], f[1][1]))
        rows = c.fetchall()
        return rows
    

if __name__==&quot;__main__&quot;:
    search = DocSearch2x2()
    search.setup()
    </pre></p>
<p>Kode di atas masih bisa dikembangkan lagi, misalnya untuk interface basisdata lain seperti mysql atau postgreS atau menggunakan SQLAlchemy. Oya, saya juga lupa, kode untuk Update belum ada <img src='http://s0.wp.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' />  .</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pebbie.wordpress.com/476/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pebbie.wordpress.com/476/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/pebbie.wordpress.com/476/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/pebbie.wordpress.com/476/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/pebbie.wordpress.com/476/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/pebbie.wordpress.com/476/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/pebbie.wordpress.com/476/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/pebbie.wordpress.com/476/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/pebbie.wordpress.com/476/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/pebbie.wordpress.com/476/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/pebbie.wordpress.com/476/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/pebbie.wordpress.com/476/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/pebbie.wordpress.com/476/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/pebbie.wordpress.com/476/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pebbie.wordpress.com&amp;blog=944265&amp;post=476&amp;subd=pebbie&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://pebbie.wordpress.com/2011/02/10/generating-python-code-for-matrix-inner-product-in-sqlite-database/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b790f5007b6f9383710eceeabe7b9e33?s=96&#38;d=wavatar&#38;r=X" medium="image">
			<media:title type="html">pebbie</media:title>
		</media:content>
	</item>
		<item>
		<title>Mengintegrasikan openCV 2.x dengan wxPython</title>
		<link>http://pebbie.wordpress.com/2011/02/10/mengintegrasikan-opencv-2-x-dengan-wxpython/</link>
		<comments>http://pebbie.wordpress.com/2011/02/10/mengintegrasikan-opencv-2-x-dengan-wxpython/#comments</comments>
		<pubDate>Thu, 10 Feb 2011 08:51:36 +0000</pubDate>
		<dc:creator>pebbie</dc:creator>
				<category><![CDATA[computer vision]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[flicker]]></category>
		<category><![CDATA[opencv]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[wxPython]]></category>

		<guid isPermaLink="false">http://pebbie.wordpress.com/?p=471</guid>
		<description><![CDATA[sebetulnya topik ini sudah lama ada, namun sepertinya tulisan-tulisan lainnya masih menampilkan kode dengan interface python versi lama. wxPython merupakan pustaka antarmuka grafis (GUI) yang berbasis wxWidget yang sudah dibungkus untuk digunakan dalam kode python. Alasan utama menggunakan pustaka GUI selain dari bawaan openCV adalah keterbatasan pustaka GUI bawaan openCV (tidak ada koleksi widget dan [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pebbie.wordpress.com&amp;blog=944265&amp;post=471&amp;subd=pebbie&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>sebetulnya topik ini sudah lama ada, namun sepertinya tulisan-tulisan lainnya masih menampilkan kode dengan interface python versi lama. wxPython merupakan pustaka antarmuka grafis (GUI) yang berbasis wxWidget yang sudah dibungkus untuk digunakan dalam kode python. Alasan utama menggunakan pustaka GUI selain dari bawaan openCV adalah keterbatasan pustaka GUI bawaan openCV (tidak ada koleksi widget dan dialog). Selain wxPython bisa juga menggunakan PyQt4 (Qt4 dibungkus untuk python). Namun, saya sedang tidak tertarik menggunakan PyQt karena hambatan lisensi. Oke, kembali ke topik utama mengintegrasikan bungkusan baru openCV. Bungkusan (wrapper) lama openCV sudah mulai tidak digunakan lagi dan tata-cara pemanggilan fungsi openCV di bungkusan yang baru lebih nyaman karena tidak banyak redundansi (misal opencv.cvQueryFrame() menjadi cv.QueryFrame() ).<br />
<span id="more-471"></span><br />
Kode berikut merupakan contoh integrasi dengan wxPython yang ada di <a href="http://opencv.willowgarage.com/wiki/wxpython">halaman wiki</a> opencv<br />
<pre class="brush: python;">import wx
import opencv.cv as cv
import opencv.highgui as gui


class CvMovieFrame(wx.Frame):
    TIMER_PLAY_ID = 101
    def __init__(self, parent):
        wx.Frame.__init__(self, parent, -1)

        self.capture = gui.cvCreateCameraCapture(-1)
        frame = gui.cvQueryFrame(self.capture)
        self.SetSize((frame.width, frame.height))
        self.displayPanel = wx.Panel(self, -1)
        cv.cvCvtColor(frame, frame, cv.CV_BGR2RGB)
        self.bmp = wx.BitmapFromBuffer(frame.width, frame.height, frame.imageData)
        self.Bind(wx.EVT_PAINT, self.onPaint)

        self.playTimer = wx.Timer(self, self.TIMER_PLAY_ID)
        wx.EVT_TIMER(self, self.TIMER_PLAY_ID, self.onNextFrame)
        fps = gui.cvGetCaptureProperty(self.capture, gui.CV_CAP_PROP_FPS)

        self.Show(True)
        if fps!=0: self.playTimer.Start(1000/fps)#every X ms
        else: self.playTimer.Start(1000/15)#assuming 15 fps

    def onPaint(self, evt):
        if self.bmp:
            dc=wx.BufferedPaintDC(self.displayPanel, self.bmp)
        evt.Skip()

    def onNextFrame(self, evt):
        frame = gui.cvQueryFrame(self.capture)
        if frame:
            cv.cvCvtColor(frame, frame, cv.CV_BGR2RGB)
            self.bmp.CopyFromBuffer(frame.imageData)
            self.Refresh()
        evt.Skip()

if __name__==&quot;__main__&quot;:
    app = wx.App()
    app.RestoreStdio()
    CvMovieFrame(None)
    app.MainLoop()</pre></p>
<p>kode ini kemudian disesuaikan sehingga menjadi </p>
<p><pre class="brush: python;">import wx
import cv #cukup 1 import


class CvMovieFrame(wx.Frame):
    TIMER_PLAY_ID = 101
    def __init__(self, parent):
        wx.Frame.__init__(self, parent, -1)

        self.capture = cv.CreateCameraCapture(-1)
        frame = cv.QueryFrame(self.capture)
        self.SetSize((frame.width, frame.height))
        self.displayPanel = wx.Panel(self, -1)
        cv.CvtColor(frame, frame, cv.CV_BGR2RGB)
        self.bmp = wx.BitmapFromBuffer(frame.width, frame.height, frame.tostring()) #imageData sudah tidak ada
        self.Bind(wx.EVT_PAINT, self.onPaint)

        self.playTimer = wx.Timer(self, self.TIMER_PLAY_ID)
        wx.EVT_TIMER(self, self.TIMER_PLAY_ID, self.onNextFrame)
        fps = cv.GetCaptureProperty(self.capture, cv.CV_CAP_PROP_FPS)

        self.Show(True)
        if fps!=0: self.playTimer.Start(1000/fps)#every X ms
        else: self.playTimer.Start(1000/15)#assuming 15 fps

    def onPaint(self, evt):
        if self.bmp:
            dc=wx.BufferedPaintDC(self.displayPanel, self.bmp)
        evt.Skip()

    def onNextFrame(self, evt):
        frame = cv.QueryFrame(self.capture)
        if frame:
            cv.CvtColor(frame, frame, cv.CV_BGR2RGB)
            self.bmp.CopyFromBuffer(frame.tostring())
            self.Refresh()
        evt.Skip()

if __name__==&quot;__main__&quot;:
    app = wx.App()
    app.RestoreStdio()
    CvMovieFrame(None)
    app.MainLoop()</pre></p>
<p>setelah dicoba dan berhasil timbul masalah baru (sepertinya hanya di windows) yaitu gambar dari webcam terlihat berkedip (sesekali). walaupun kode di atas sudah menggunakan doublebuffering (wx.BufferedPaintDC) seperti yang dianjurkan oleh wxPython, namun sepertinya tidak mempan kalau dijalankan di Windows (saya coba di Win7). Cara lain untuk menghilangkan kedipan ini ditunjukkan di mailing-list <a href="http://groups.google.com/group/wxpython-users/browse_thread/thread/80df84b2cbd2c7a2/529089264ca2e7f8?pli=1">wxPython-users</a> dengan catatan perlu menggunakan pustaka khusus windows yaitu pythonwin32 seperti di kode berikut.</p>
<p><pre class="brush: python;">import wx 
import win32api 
import win32con 
import sys 
import cv 
sys.path.append('C:\OpenCV2.1\Python2.6\Lib\site-packages') 
class captureTest(wx.Frame): 
    TIMER_PLAY_ID = 101 
    def __init__(self, parent): 
        wx.Frame.__init__(self, parent, -1) 

        def SetCompositeMode(self, on=True): 
            exstyle = win32api.GetWindowLong(self.GetHandle(), win32con.GWL_EXSTYLE) 
            if on: 
                exstyle |= win32con.WS_EX_COMPOSITED 
            else: 
                exstyle &amp;= ~win32con.WS_EX_COMPOSITED 
            win32api.SetWindowLong(self.GetHandle(), win32con.GWL_EXSTYLE, exstyle) 

        SetCompositeMode(self, True) 
        self.capture = cv.CaptureFromCAM(0) 
        capImg = cv.QueryFrame(self.capture) 
        self.SetSize((capImg.width, capImg.height)) 
        self.displayPanel = wx.Panel(self, -1) 
        cv.CvtColor(capImg, capImg, cv.CV_BGR2RGB) 
        self.buildBmp = wx.BitmapFromBuffer(capImg.width, capImg.height, capImg.tostring()) 
        self.Bind(wx.EVT_PAINT, self.onPaint) 
        self.playTimer = wx.Timer(self, self.TIMER_PLAY_ID) 
        wx.EVT_TIMER(self, self.TIMER_PLAY_ID, self.onNextFrame) 
        fps = cv.GetCaptureProperty(self.capture, cv.CV_CAP_PROP_FPS) 
        self.Show(True) 
        if fps!=0: self.playTimer.Start(1000/fps) #every X ms 
        else: self.playTimer.Start(1000/15) #assuming 15 fps 

    def onPaint(self, evt): 
        if self.buildBmp: 
            dc=wx.BufferedPaintDC(self.displayPanel, self.buildBmp) 
        evt.Skip() 

    def onNextFrame(self, evt): 
        capImg = cv.QueryFrame(self.capture) 
        if capImg: 
            cv.CvtColor(capImg, capImg, cv.CV_BGR2RGB) 
            self.buildBmp.CopyFromBuffer(capImg.tostring()) 
            self.Refresh() 
        evt.Skip() 

if __name__==&quot;__main__&quot;: 
    app = wx.App() 
    app.RestoreStdio() 
    captureTest(None) 
    app.MainLoop()</pre></p>
<p>Kode tersebut belum saya coba, karena di komputer yang saya gunakan belum terpasang pustaka pythonwin32. Setelah meneruskan membaca sambil mencoba ternyata di diskusi tersebut juga ada jawabannya yaitu tidak menggunakan Timer tetapi memanfaatkan event EVT_IDLE. kode akhirnya seperti ini (catatan tambahan, saya mengabaikan frame-per-second dari data video):<br />
<pre class="brush: python;">import wx
import cv


class CvMovieFrame(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, parent, -1)

        self.capture = cv.CreateCameraCapture(-1)
        
        frame = cv.QueryFrame(self.capture)
        self.SetSize((frame.width, frame.height))
        self.displayPanel = wx.Panel(self, -1)
        cv.CvtColor(frame, frame, cv.CV_BGR2RGB)
        self.bmp = wx.BitmapFromBuffer(frame.width, frame.height, frame.tostring())
        self.Show(True)
        
        self.Bind(wx.EVT_IDLE, self.onIdle)

    def onIdle(self, event):
        self.nextFrame()
        event.RequestMore()

    def nextFrame(self):
        img = cv.QueryFrame(self.capture)
        cv.CvtColor(img, img, cv.CV_BGR2RGB)
        self.bmp.CopyFromBuffer(img.tostring())
        dc = wx.ClientDC(self.displayPanel)
        dc.DrawBitmap(self.bmp, 0, 0, False)
        

if __name__==&quot;__main__&quot;:
    app = wx.App()
    app.RestoreStdio()
    CvMovieFrame(None)
    app.MainLoop()</pre></p>
<p>Kode di atas ternyata cukup memuaskan. tidak ada lagi kedipan ketika menggambar frame baru.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pebbie.wordpress.com/471/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pebbie.wordpress.com/471/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/pebbie.wordpress.com/471/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/pebbie.wordpress.com/471/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/pebbie.wordpress.com/471/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/pebbie.wordpress.com/471/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/pebbie.wordpress.com/471/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/pebbie.wordpress.com/471/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/pebbie.wordpress.com/471/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/pebbie.wordpress.com/471/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/pebbie.wordpress.com/471/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/pebbie.wordpress.com/471/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/pebbie.wordpress.com/471/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/pebbie.wordpress.com/471/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pebbie.wordpress.com&amp;blog=944265&amp;post=471&amp;subd=pebbie&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://pebbie.wordpress.com/2011/02/10/mengintegrasikan-opencv-2-x-dengan-wxpython/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b790f5007b6f9383710eceeabe7b9e33?s=96&#38;d=wavatar&#38;r=X" medium="image">
			<media:title type="html">pebbie</media:title>
		</media:content>
	</item>
	</channel>
</rss>
