anlak.com
Showing posts with label programlama. Show all posts
Showing posts with label programlama. Show all posts

Kısıtları türevlenebilirleştirmece(!) numarası

, Friday, 6 June 2014
Diyelim ki eşitsizlik biçiminde ifade edebildiğiniz bazı kısıtlarınız var ve bu eşitsizlikleri sağlayacak bir çözüm arayışındasınız. Bu yazıda bunu elde etmeyi sağlayacak bir numara göstereceğim.

Problemimizi daha iyi tanımlayalım: öyle bir $x$ arıyoruz ki $g(x) \le 0$ olsun. $g(x)$ sürekli ve türevlenebilir olsun bir de. Genelde elimizdeki eşitsizlikleri biraz cebirsel oynamayla $g(x) \le 0$ şeklinde yazabiliriz.

Şimdi, $t \le 0$ eşitsizliğini sağlayan bütün $t$ değerlerinin $\max(0, t) = 0$ eşitliğini de sağladığını farkedelim. Bu demek oluyor ki  $t \le 0$ gördüğümüz her şeyi $\max(0, t) = 0$ gibi değerlendirebiliriz.

Yalnız $\max(0, t)$ ifadesi pek yumuşak değil, o yüzden karesini alıp yumuşatalım. Gene $t \le 0$ eşitsizliğini sağlayan $t$ değerleri $\max(0, t)^2 = 0$ eşitliğini sağlar.

Geldik son adıma, yukarıda bahsettiğimiz ifadelerde $t$ yerine $g(x)$ koyup şu problemi çözelim:
$$
\text{minimize } \max(0,g(x))^2
$$
Yukarıdaki problemde hedef fonksiyonun değeri 0 olduğunda istedğimiz bir çözüm bulunmuş olur. Bunu bulmak için de en basitinden gradient descent gibi bir yöntem kullanabiliriz, ne de olsa hedef fonksiyonumuz mis gibi türevlenebilir. Elbette yerel minimalara takılma şansınız var, hatta çözüme hiç bir zaman ulaşamayabilirsiniz.

Özetle, elinizdeki eşitsizlikleri gösterdiğim numara ile türevlenebilir bir fonksiyon halinde yazabilirsiniz.

Örnek Uygulama

Tarif ettiğim numarayı oyuncak bir problem üzerinde göstereyim, biraz balyozla sinek avlamaya benzeyecek ama daha anlasilir olacak. Verilen bir alana, belli bir boyuttaki dikdörtgeni nasıl sığdırabileceğimize bakalım. Dikdörtgeni döndürmek serbest. Aşağıdaki çizimde problemi tarif etmeye çalıştım.



Diyelim ki elinizde $\Omega=\{x\in \mathbb{R}^2 \mid f_j(x)\le 0, j=1,\dots,m \}$ tanımlanmış bir alan olsun. Elimizde de $(c, w, h, \theta)$ ile parametrize ettiğimiz bir dikdörtgen olsun. $c$, dikdörtgenin merkezinin konumu, $w$ ve $h$ genişliği ve yüksekliği, $\theta$ da döndürme açısı olsun, ayrıca kolaylık olsun diye $w$ ve $h$ bize önceden verilmiş olsun. Problemi ben uydurduğum için buna hakkım olsun :)

Dikdörtgeni verilen alanın içine sığdıracak $(c, \theta)$ arıyoruz. Dikdörtgenin alanın içinde olabilmesi için, 4 köşesinin de alanın içinde olması lazım, yani:
$$
f_j(p^i) \le 0 \text{ for all } j=1,\dots\,m \text{ and } \\ i=\{\text{SOLÜST, SAĞÜST, SOLALT, SAĞALT}\}
$$
Dikdörtgenin bir köşesinin ifadesini yazalım, diğer köşeler de benzer şekilde yazılabilir:
$$
p^{\text{SOLÜST}}=c+R(\theta) \begin{bmatrix} -0.5 w \\ -0.5 h \end{bmatrix}
$$
Yukarıdaki ifadede $R(\theta)$ döndürme matrisi, yani $R(\theta) = \left[\begin{smallmatrix}
cos(\theta) & -sin(\theta) \\ sin(\theta) & cos(\theta)
\end{smallmatrix} \right]$.

Şimdi, en başta bahsettiğim dönüşüm numarasını uygularsak problemimiz şu biçime dönüşür:
$$
\text{minimize} \sum_j \sum_i \max(0,f_j(p^i))^2
$$
Ben örneğimiz için döndürülmüş bir elips olan tek bir $f(\cdot)$ seçtim ve gradient descent ile çözdüm:
$$
f(x, y) = \frac{((x-2)\cos(\alpha) + (y-4)\sin(\alpha))^2}{4} + \frac{((x-2)\sin(\alpha) - (y-4)\cos(\alpha))^2}{16} - 1;
$$

Türevleri almak için MATLAB'ın sembolik kütüphanesini kullandım, bu işi ilk defa yaptığım için çok iğrenç bir kod oldu. Kötü kodlarımı paylaşmaya utandığımdan buraya koymadım. Aşağıda gradient descent algoritmasının bazı adımlarını görebilirsiniz:


Yazdığım yazılarda gittikçe anlaşılma derdimi yitirdiğimi görüyorum. Umarım oralarda hala beni anlayan birileri vardır :)

MATLAB değişken ismi değiştirme

, Friday, 10 May 2013
MATLAB 2011b'den beri çok güzel bir özellik varmış da haberim yokmuş. Bir değişken ismini, "Find & Replace" yapmadan, kullandığınız her yerde kolayca değiştirebiliyorsunuz.

Bunun için imleç değişkenin üzerindeyken yeni değişken ismini yazıp Shift+Entera basıyorsunuz.


Yalnız bu yöntemin bazı kısıtları var:
  • İmleç, eşitliğin solundaki ya da fonksiyon argümanındaki değişkendeyken isim değiştirilebiliyor

  • Fonksiyon isimleri, fonksiyonun tanımlandığı yerden değiştirilebiliyor

  • varargin varargout gibi özel anlamı olan isimler değiştirilemiyor
Bu gelişmeler çok güzel ama hala Java ve C# gibi dillerin sunduğu refactor becerilerinin yanına yaklaşmaktan çooook uzaklar.

Kayan noktalı (floating point) sayı kıyaslama

, Friday, 29 March 2013
Sayılamaz sonsuzlukta reel sayıların ancak çok sınırlı sayıda bir kısmını bilgisayarda temsil edebiliyoruz. Bu yüzden yaptığımız hesaplarda gerçek sonuçtan biraz farklı bir değer elde ediyoruz. Kimi zaman da bu küsüratlı sayıları kıyaslamamız gerekiyor.

Bu kıyaslama işlemi fazlasıyla sıkıntılı bir iş. Pratikte çoğunlukla işe yarayacak ipuçlarını paylaşayım dedim. Kolaylık olsun diye yazının geri kalanında kayan noktalı sayılar için double kelimesini kullanacağım, söylediğim şeyler float gibi herhangi bir kayan noktalı sayı gösterimi için geçerlidir.

Altın kural: Asla, ama asla, iki double'ı == ya da != gibi karşılaştırma operatörleriyle doğrudan kıyaslamayın. Çoğunlukla eşit olmayacaklardır.
  1. Yaklaşık eşitliği sınayan fonksiyonunuz olsun, heryerde aynısını kullanın.
    approxEqual(double a, double b, double eps=machine_epsilon) 
        return abs(a-b) <= max(a,b)*eps;
    max() yerine min() de kullanılabilir. Bunu yapınca tabi ki fonksiyonun davranışı değişecek, mühim olan hassasiyetinizi kıyaslanacak sayılara göre ölçeklemek.
  2. Bir double'ı sıfırla kıyaslayacaksanız işler karışıyor. Genelde kıyaslayacağınız sayı kabul edilebilir seviyede küçük, fakat sıfırdan hatrı sayılır derecede (hatta sonsuz kat) büyük olacaktır. Yukarıdaki approxEqual()bu durumda işe yaramayacaktır. Sıfırla kıyaslama durumunu ayrıca değerlendirin.
    approxZero(double d, double eps=machine_epsilon)
        return abs(d)<=eps;
  3. İki sayının farkını sıfırla kıyaslamak yerine, iki sayıyı birbiriyle kıyaslayın. Bir önceki maddede açıkladığım gibi sıfırla kıyaslama daha problemli bir iş.
  4. Bu iki yaklaşım da tam olarak doğru yaklaşımlar değil aslında, ama çoğunlukla işinizi görecektir. Hassasiyet hatalarıyla başetmenin kesin yolu hatanın analizini yapıp yukarıdaki fonksiyonlarda eps değişkeninin varsayılan değerini kullanmak yerine hesapladığınız teorik hataya göre bir eps seçmek. Bunu yapmak genelde çok zor. İkinci yol ise deneme yanılma; işinize yarayacak epsilon değerini el yordamıyla bulacaksınız.
  5. Kayan noktalı sayılarla işlem yapmaca göründüğünden ve sandığınızdan çok daha zor ve karmaşık bir iş. Örneğin kıyasladığınız iki sayıdan birinin sıfır olma ihtimali varsa allah yardımcınız olsun.
Yukarıda machine_epsilon diye kodladığım değişkeni genelde kullandığınız programlama dili size bir sabit olarak verir, dökümantasyonunuza bakın.

Dediğim gibi kayan noktalı sayılar çok derin bir konu ve ancak şöyle bir üzerinden yalayıp geçtim. Yazdığım kadarı günlük kullanım için yeterli olur herhalde.

Using OpenCV 2.3.1 with Visual Studio 2010 (tutorial)

, Tuesday, 27 September 2011
There is a newer version of this document: Using OpenCV 2.4.x with Visual Studio 2010

Here in this tutorial I am going to show how to configure Visual Studio 2010 to use OpenCV 2.3.1 in your computer vision projects. Also, I am going to write a couple of lines of code to show new OpenCV C++ API.

By the time the tutorial was written the latest version of OpenCV was 2.3.1. The methods described below should, but may not, work for different versions. This tutorial targets computer vision course students at Computer Engineering in BOUN, but I will be generalizing as much as I can, so everyone can enjoy it.

Foreword

Before starting I would like to suggest a couple of things.

First, if you are ever going to write C++ code, read Effective C++, 3rd edition by Scott Meyers (CAUTION! 2nd edition is outdated, it is not worth reading imho). This book has many topics on how to write correct, working, easily maintainable C++ code. I see lots of boilerplate code around when it comes to C++, not only reading this book will reduce such practices, it will save you time. Besides, you will feel healthy mind-wise :) If there was to be only one book on C++, and the rest was to disappear, I would select this book. Be careful though, this book is *NOT* for beginners, you need to know a little bit of C++ to understand what it means.

For BOUN students who are taking Computer Vision course, the book is available as an electronic resource in the library.

Second, Google has really good guidelines on different programming languages, including C++. Although they are specialized for their internal use, I recommend following those guidelines. The guideline provide the motivation behind the rules, so it is also great place to learn how to write C++ properly. Again, it is not a place to learn C++, but to master C++.

Preparation

Make sure that you have Visual Studio 2010 (VS2010) installed.

For BOUN students, it is available in license server. I don't quite know the details, you may need to work it on your own.

Download OpenCV 2.3.1 and extract the contents to a folder. I prefer to put directly under root like "C:\OpenCV-2.3.1\".

Optionally, I recommend using Visual Assist X to write and refactor code easily.

Configuring VS2010

There are a couple of ways to configure Visual Studio 2010, I am going to show a way which I find convenient. We are going to configure it using property sheets. Whenever we need to create another project, we just need to add same property sheets to new project. Let's start.

Launch VS2010 and select "New project...".

Select "Empty Project", enter "hello-opencv" as Name, select a location to place project. I also prefer, for simplicity, not creating directory for solution so I unchecked that option. See the image below.

When done, press "OK".

Now we have created a project from scratch. It is time to link the libraries and make our project use OpenCV.

Switch to Property manager by clicking on the tab below.

The default properties are for 32-bit systems (note the Win32 suffixes), because I am using 64-bit system, from now on I am going to describe the configuration for 64-bit systems.

From the "Build" menu, select "Configuration Manager". Under "Active solution platform" Win32 should be selected by default. Click on it and select "New...".

Select "x64" as the new platform and select Win32 to copy settings from. Make sure that "Create new project platforms" is checked.

Now your Property Manager view should look like this:

Select the Win32 configurations and delete them, you won't be needing those. Let me remind this one more time, these steps are only required if you are using 64-bit system and want to develop 64-bit applications.

To add a property sheet right click on "Debug | x64" and select "Add New Project Property Sheet". This property sheet will/should only include the details on how to link the OpenCV library to our project. Once this is done, the property sheet can be shared between projects on the same computer.

On the add new property sheet dialog, I entered "OpenCV-Debug" as the sheet name, because this sheet will link debug libraries. After pressing "Add" the new property sheet will show up in Property Manager. Double click on it, a dialog with lots of properties will be shown.

Under "Common Properties" -> "C/C++" -> "General", edit "Additional Include Directories" and add "C:\OpenCV-2.3.1\build\include". Of course don't forget to change the path accordingly if you have put OpenCV files to a different place. It is important that you select the "include" folder under "build" folder, not any other "include" folder.

Under "Common Properties" -> "Linker" -> "General", edit "Additional Library Directories" and add "C:\OpenCV-2.3.1\build\x64\vc10\lib". I won't tell you to change the path to your OpenCV path next time :) Here "x64" stands for 64-bit systems, if you are using 32-bit change it to x86. "vc10" stands for Visual C++ 2010, leave it as it is assuming you are using VS2010.

Under "Common Properties" -> "Linker" -> "Input", edit "Additional Dependencies" and add the following lib files:

opencv_calib3d231d.lib
opencv_contrib231d.lib
opencv_core231d.lib
opencv_features2d231d.lib
opencv_flann231d.lib
opencv_gpu231d.lib
opencv_haartraining_engined.lib
opencv_highgui231d.lib
opencv_imgproc231d.lib
opencv_legacy231d.lib
opencv_ml231d.lib
opencv_objdetect231d.lib
opencv_ts231d.lib
opencv_video231d.lib


Actually you won't probably need all the libraries. Linking the only necessary ones may make linking operation a little bit faster but for our case, that speed up is not worth the effort. Note the letter "d" in filenames just before the dot, that "d" stands for "Debug".

The steps are the same for "Release" configuration except the linked library filenames. You just need to get rid of the "d" letters before the dot. Debug libraries includes additional instructions for debugging purposes such as variable watching, and they are not optimized. This makes debug libraries run slower. When you are dealing with lots of data or you just need more processing power you should switch to release configuration which is free of extra instructions and optimizes your code, hence runs much faster.

Hello OpenCV

OK. Now we are (almost) ready to write our first lines of code. Switch to "Solution Explorer" by clicking the tab below. Right click on "Source Files", select "Add" -> "New Item...". Select "C++ File" from the menu and type "main" as name.


Insert the following lines into the main.cpp and run the code (press F5).

#include <opencv2/opencv.hpp>

using namespace cv;

int main()
{
    Mat img(Mat::zeros(100, 100, CV_8U));

    imshow("window", img);

    waitKey();

    return 0;
}

You should get an error about a missing dll. Locate "hello-opencv.exe" in your project folder. Copy the dll files (preferably the ones that ends with letter "d") from "C:\OpenCV-2.3.1\build\x64\vc10\bin" to that folder.

By the way, using full namespaces like "using namespace cv;" is discouraged. I recommend using "using cv::Mat;", this will prevent name collisions and make the code more maintainable. See this discussion for details.

Some people prefer adding these dll into PATH environment variable, I prefer my projects to be self sufficient. It is good to be in control of which dll the project is using. If you are dealing with multiple projects using the different versions of the same library, if the dll names are the same, PATH approach will not work.

Run the code again. It should work fine and display a 100x100 black image in a window. If not that means there is a problem that you need to figure out. Try until you solve that problem.

Now modify the main.cpp so it is like:

#include <opencv2 /opencv.hpp>

using namespace cv;

int main()
{
    Mat img;
    VideoCapture cap(0);

    while (true)
    {
        cap >> img;

        Mat edges;
        cvtColor(img, edges, CV_BGR2GRAY);

        Canny(edges, edges, 30, 60);

        imshow("window label", edges);
        waitKey(1);
    }

    return 0;
}

The code above needs a webcam connected to the computer, it captures images from a camera.

And run the code. You should get a missing "tbb_debug.dll" error. This is a bug of OpenCV-2.3.1. It should be shipped with tbb_debug.dll but it is missing in the package. That dll is the part of Threading Building Blocks project by Intel, you should download the latest version from here. The zip file that you have downloaded contains the dll, and you should copy that dll to the same folder under your project like other dlls (same directory as hello-opencv.exe).

Now run the code again. "Canny" is an edge detection algorithm, if the program runs well, you should see the detected edges of the captured image.


This completes our tutorial.

Closure

The documentation of OpenCV is quite good. Use it extensively.

I highly recommend using new OpenCV C++ API. The new API is clean, slick and well-designed. Avoid using old API, e.g. IplImage, unless you really know what you are doing. There are lots of information on internet about OpenCV which is outdated, beware of those. Always use the latest official documentation first.

Basit JavaShell

, Monday, 25 February 2008

Giriş

JavaShell classı basit bir Java command line interface ile programdaki belirli fonksiyonlari direkt cagirabilmek icin bir ornektir.

Kullanım

method = JavaShell.class.getMethod(cmd, new Class[] {});
method.invoke(JavaShell.class, new Object[] {});
ile bulundugu class icindeki metodlar direkt cagrilabilir. Onemli kisit metodlarin public deklare ediliyor olma gereksinimidir. Public olmayan metodlara erisim icin kullanilamaz.

Örnek

JavaShell V01 by Keyholder
Date:Sun Feb 24 01:18:50 EET 2008
$>
olmayan_metod
Command not found
$>
exit
Bye bye

Download

JavaShell by keyholder

Google OCR veri seti

, Tuesday, 8 January 2008
Daha önce OCR sistemlerinizi test etmek ya da eğitmek için kullanabileceğiniz sınırlı bir karakter verisetini burada paylaşmıştım.

Verisetine ihtiyaç duyanlar bunları elde etmenin ne kadar zor olduğunu bilirler. Hayat kurtarıcı sürpriz Google'dan geldi. ICDAR2007'de (Uluslararası Döküman Analiz ve Tanıma Konferansı) konuşmacı olarak yer alan Luc Vincent'ın müjdelediğine göre, Google şimdiye kadar Google Book Search sürecinde elde ettikleri, telif hakkı olmayan, verileri bir araya getirip araştırmacılar için kapsamlı bir veriseti hazırlama sürecine girmiş.

İlk ürünleri bir an evvel alabilmemiz umuduyla.

Kaynak: Google Book Search: Document Understanding on a Massive Scale, Vincent L.

Java Karakter Sayaci

, Monday, 31 December 2007
Harflerin sayi gibi muamele gormesi icin hazirlamis oldugum java methodu. Bir vakit yazdigim bir test simulatorunde string test serileri uretmek icin kullanmis idim. Ornekler: a verilir , b alinir aab verilir, aac alinir daz verilir , dba alinir bzz verilir , caa alinir zz verilir, aaa alinir StringCounter.java by keyholder

Bölütlenmiş Karakterler v0.1

, Saturday, 30 September 2006
Bölütlenmiş Karakterler, optik karakter tanıma(OCR) gibi uygulamalarınızda test/eğitim amacıyla kullanılabilecek 0-9 arası rakam ve büyük harflerden oluşan bir veri setidir. Veriler gerçek dünyadan edinildiği için veriler gürültülüdür. An itibariyle hayli eksik olduğundan varolan veri setinizi genişletmek amacıyla kullanabilirsiniz. Yanlışlıkları bitkidoku *AT* anlak *NOKTA* com eposta adresine bildirirseniz sevinirim.

Verisetinden örnekler:


Hangi karakterden kaç adet var?

Karakter adet
0 100
1 114
2 131
3 92
4 111
5 92
6 102
7 87
8 124
9 105
A 191
B 70
C 69
D 4
E 6

Karakter adet
F 1
G 3
H 31
K 92
L 6
M 58
N 5
O 4
P 47
T 26
V 1
X 144
Y 4
Z 2
. .
toplam: 1821



Internet uzerinde bulunan benzer veri setlerinden bazilari:

C bulmacası

, Tuesday, 6 June 2006
"condition" nedir ki aşağıdaki kod parçası Hello ve World 'ün ikisini de yazsın.
if "condition"
    printf ("Hello");
else
    printf ("World"); 
Çözüm