Character Segmentation from the Image [Continued]

Yeah, this time I will introduce about character segmentation in details[Code] from the previous entry.
First of all,you should load this tester image for workshop.

image.jpg (11.77 kb)


OK, this workshop works on Python language with Python Image Library. http://www.pythonware.com/products/pil/index.htm

There are 5 parts in this workshop.
1. Preprocessing -> prepare image before do the main process.
2. Find histograms in both directions -> to be used in step 3.
3. Find pair of concave up and down points -> to find segmentation points.
4. Segmentation.
5. Show Results.

Recall from the previous entry.
In Preprocessing, we need to load the image in grayscale image. Next, clean the image. Then, convert to a binary image.


# load and convert image to a grayscale image.
im = Image.open('image.jpg').convert("L") 
(width, height) = im.size
# use median filter size 11x11 to clean image
mim = im.filter(ImageFilter.MedianFilter(11))
# extract foreground from background by using threshold value.
# using threshold = 8, then use median filter to clean image again.
cim = mim.point(lambda i: i*8,"F").convert("1").filter(ImageFilter.MedianFilter(11))

We will get the result like this. [Use cim.show() to show an image]

Next, we have to find histograms in horizontal and vertical lines.

#main process part
# load image to 2d
pix = cim.load()

#find histograms in both directions
hhist = []
s = 0
for h in range(height):
    for  w in range(width):
        if(pix[w,h]==0):
            s+=1
    hhist.append(s)
    s = 0
    
vhist = []
s = 0
for w in range(width):
    for  h in range(height):
        if(pix[w,h]==0):
            s+=1
    vhist.append(s)
    s = 0

Then, we have to find cutting point from the image by seeing from histogram value that goes up from 0 to upper and goes down from more than 0 to 0.

#find pair of concave up and down points
hup = []        #keep concave up index [horizontal]
hdown = []      #keep concave down index [horizontal]
s = len(hhist)
for x in range(1,s):
    if(hhist[x-1]>0 and hhist[x]==0):
        hdown.append(x-1)
    if(hhist[x-1]==0 and hhist[x]>0):
        hup.append(x)

vup = []        #keep concave up index [vertical]
vdown = []      #keep concave down index [vertical]
s = len(vhist)
for x in range(1,s):
    if(vhist[x-1]>0 and vhist[x]==0):
        vdown.append(x-1)
    if(vhist[x-1]==0 and vhist[x]>0):
        vup.append(x)

Finally, we will segment an image and then show the result of all characters. We have to create a box for crop an image (left,upper,right,lower) that upper and lower will use values from hup and hdown respectively.

#segmentation
# we know that we have only 1 line so, hup and hdown are not change.
# if we want to show all segmented images, it will change in vup and vdown indexes.

for i in range(len(vup)):
    box = (vup[i],hup[0],vdown[i],hdown[0])
    seg = cim.crop(box)

#show result
    seg.show()

                            

Now, we will know about the concept of image segmentation that is not hard for implement. It may expand your thought to develop a more complicated segmentation ^^.

Categories:   Image Processing
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | RSS


A Brief Introduction to Multi-threading in C# (Part2:Manage Threads Manually)

From the previous post, Part1:CLR-Managed Thread, what if you want absolute control over the execution of the threads. Here are the ways:

- Thread Monitor

Concurrent executions of threads, which's called race conditions, can bring the whole application down due to the inconsistency of the application state or variable. Monitor can guarantee thread safe. It means that , it will ensure that your code's executed in a synchronized fashion. Monitor.Enter and Monitor.Exit define a critical section for your code. Example:

 

public class Task
        {
            public string TaskName { get; set; }
            public Task(string taskName)
            {
                TaskName = taskName;
            }
            public bool Commit()
            {
                Console.WriteLine("Task : " + TaskName + " was done!");
                return true;
            }
        }
        public class Robot
        {
            //initialize taskList as a thread-safe queue.
            private Queue _TaskList = Queue.Synchronized(new Queue());
            public string Name { get; set; }

            public void AddTask(Task task)
            {
                _TaskList.Enqueue(task);
            }
            public void PerformTaskList(object syncObj)
            {
                //lock task list, so other robots cannot perform the same list.
                Monitor.Enter(syncObj);
                //suppose:  2 sec initialize then commit task list.Thread.Sleep(2000);
                Console.WriteLine("ROBOT '" + Name+"' is executing... ["+DateTime.Now.TimeOfDay+"]");
                Thread.Sleep(2000);
                foreach (Task task in _TaskList) task.Commit();
                Console.WriteLine("ROBOT '" + Name + "' finishes executing... ["+DateTime.Now.TimeOfDay+"]\n");
                Monitor.Exit(syncObj);
            }
        }
static void Main(string[] args)
        {
            Robot robo1 = new Robot() { Name = "Steven" };
            Robot robo2 = new Robot() { Name = "Bill" };
            Task task1 = new Task("Clean the room");
            Task task2 = new Task("Cook a meal");
            robo1.AddTask(task1);
            robo1.AddTask(task2);
            robo2.AddTask(task1);
            robo2.AddTask(task2);
            object syncObj = new object();
            ThreadPool.QueueUserWorkItem(new WaitCallback(robo1.PerformTaskList), syncObj);
            ThreadPool.QueueUserWorkItem(new WaitCallback(robo2.PerformTaskList), syncObj);

            Console.ReadLine();
        }

Robo2'll wait for robo1 to finish its execution (syncObj'll do sycn lock for us). The shortcut of Monitor.Enter(obj) and Monitor.Exit(obj) is lock(obj){ ... }. Try it by yourself!

 

- Interthread Signaling 

Imagine that 2 robots working together, robo1 receives task on the carousal and notifies robo2 to process that task. The second task comes in, the process of receiving and processing are still the same cycle by cycle. Carousal is like a pipeline event that enables robots working together. So, robo1 must signal robo2 to do its job. I'll show how robots complete their common tasks by using the notification ManualResetEvent and AutoResetEvent (both of them derived from EventWaitHandle which in turn derived from WaitHandle as introduced in Part1) (Note that some parts of code are modified for the demonstration): 

public class Robot
    {
        //worker thread to process the task assigned for this robot.
        protected Thread processingThread;
        //initialize taskList as a thread-safe queue.
        public Queue TaskList { get; set; }

        public string Name { get; set; }
        public ManualResetEvent NotificationEvent { get; set; }
    }
public class ReceiverRobot : Robot
    {
        //this part is processed on the application's thread.
        public void ReceiveTask(Task task)
        {
            TaskList.Enqueue(task);
            //send signal to processingThread that's waiting that the task's come in.
            NotificationEvent.Set();
        }
    }
    public class ProcesserRobot : Robot
    {
        public ProcesserRobot()
        {
            //create and start a new worker thread.
            processingThread = new Thread(new ThreadStart(PerformCommonTaskList));
            processingThread.Start();
        }
        //this method's processed on a worker thread.
        public void PerformCommonTaskList()
        {
            while (true)
            {
                //wait the receiver robot to assign the task.
                NotificationEvent.WaitOne();
                //reset the signal back to nonsignal state.
                //for AutoResetEvent you don't need this line; it'll reset automatically after event's signaled(set)
                NotificationEvent.Reset();
                while (TaskList.Count > 0) ((Task)TaskList.Dequeue()).Commit();
            }
        }
    }

        static void Main(string[] args)
        {
            //create a single pipeline event used for intercommunicating (false - initially set to nonsignal state).
            ManualResetEvent pipelineEvent = new ManualResetEvent(false);
            //create shared taskList.
            Queue taskList = Queue.Synchronized(new Queue());

            ReceiverRobot robo1 = new ReceiverRobot();
            robo1.NotificationEvent = pipelineEvent;
            robo1.TaskList = taskList;
            ProcesserRobot robo2 = new ProcesserRobot();
            robo2.NotificationEvent = pipelineEvent;
            robo2.TaskList = taskList;

            Task task1 = new Task("Clean the room");
            Task task2 = new Task("Cook a meal");
            robo1.ReceiveTask(task1);
            robo1.ReceiveTask(task2);

            Console.ReadLine();
        }

Not only applicable to this 2 robot, but imagine this as a bunch of pipeline workers. So far, I'll have to let you develop further thought for you own interthread communication.

That's enough for today. Stay tuned for the next part... : - )

kick it on DotNetKicks.com  Shout it

Categories:   .NET ASP.NET C# | Tip(s)
Actions:   E-mail | del.icio.us | Permalink | Comments (3) | RSS


A Brief Introduction to Multi-threading in C# (Part:Automatic Threads)

Hello again, today post is a brief intro of multi-threading that i read from a book (http://www.amazon.com/Practical-Financial-Markets-Experts-Voice/dp/1590595645) and summarize it here. If you want to do multithreading there're a plenty of ways:

- Thread Pools: the most easiest because it's auto-managed by CLR already, you just tell them what task you want them to process and thada!. The pool also knows how to utilize the CPU. If its tasks're full-loaded, the pool won't create anymore threads. There're 2 kinds of thread in Thread Pools 1) worker threads 2) I/O threads(e.g. reading data from I/O, Socket, or Network). The default settings'd be 25 worker, 25 I/O threads. If there's no available thread to process a new task, it'll queue that task for a while. For the sample code:

 

public class Task
        {
            public string TaskName { get; set; }
            public Task(string taskName)
            {
                TaskName = taskName;
            }
            public bool Commit()
            {
                Console.WriteLine("Task : " + TaskName + " was done!");
                return true;
            }
        }

        static void Main(string[] args)
        {
            //param1: callback method, param2: callback method's parameters
            ThreadPool.QueueUserWorkItem(new WaitCallback(ProcessTask), new Task("Clean the house"));
            ThreadPool.QueueUserWorkItem(new WaitCallback(ProcessTask), new Task("Do breakfast for me"));
ThreadPool.QueueUserWorkItem(new WaitCallback(ProcessTask), new Task("Drive me a car"));
Console.ReadLine(); } public static void ProcessTask(object task) { ((Task)task).Commit(); }

 

No need to explain, pretty simple and easy. Note that the callback method must be static method.

- Asynchronous Delegate Method: as the title suggested, I will use Delegate to enable async method call.  The behind the scene of BeginInvoke and EndInvoke use ThreadPools to gain CPU utilization as well: 

public class Task
        {
            public string TaskName { get; set; }
            public Task(string taskName)
            {
                TaskName = taskName;
            }
            public bool DoWork()
            {
                Console.WriteLine("Task : " + TaskName + " was done!");
                return true;
            }
        }
        public class TaskStatus
        {
            public TaskStatus(string taskName,bool isCompleted)
            {
                TaskName = taskName;
                IsCompleted = isCompleted;
            }
            public string TaskName{get;set;}
            public bool IsCompleted { get; set; }
        }

        public delegate TaskStatus TaskHandler(Task task);

        static void Main(string[] args)
        {
            //assign ProcessTask method to TaskHandler delegate (their signatures must be matched!)
            TaskHandler processTaskHandler = new TaskHandler(ProcessTask);
            //begine async method call
            IAsyncResult result = processTaskHandler.BeginInvoke(new Task("Clean the house"), null, null);
            //Ok! stay here (block the current thread) until ProcessTask's completed (wait not more than 2 sec).
            result.AsyncWaitHandle.WaitOne(2000);
            //get the result from the operation (ProcessTask).
            TaskStatus status = processTaskHandler.EndInvoke(result);

            Console.WriteLine(status.TaskName + ((status.IsCompleted)?" is completed.":" is failed."));

            Console.ReadLine();
        }

        public static TaskStatus ProcessTask(object t)
        {
            Task task = (Task)t;
            TaskStatus status = new TaskStatus(task.TaskName, task.DoWork());
            return status;
        }

Using this may troublesome cause you have to if the status of operation is already completed by using WaitHandler. Alternatively, you can assign notification callback method to BeginInvoke as well. When complete BeginInvoke, it'll execute notification callback and now you don't need to handle WaitHandler anymore.

//others're the same as in the section above.
static void Main(string[] args)
        {
            //assign ProcessTask method to TaskHandler delegate (their signatures must be matched!)
            TaskHandler processTaskHandler = new TaskHandler(ProcessTask);
            AsyncCallback processTaskCompleted = new AsyncCallback(ProcessTaskCompleted);
            //begin async method call, also pass notification callback and ProcessTask handler.
            IAsyncResult result = processTaskHandler.BeginInvoke(new Task("Clean the house"), processTaskCompleted, processTaskHandler);

            Console.ReadLine();
        }

public static void ProcessTaskCompleted(IAsyncResult result)
        {
            //get the delegate object after the async call's invoked.
            TaskHandler processTaskHandler = (TaskHandler)((System.Runtime.Remoting.Messaging.AsyncResult)result).AsyncDelegate;
            //get the result from the operation (ProcessTask).
            TaskStatus status = processTaskHandler.EndInvoke(result);
            Console.WriteLine(status.TaskName + ((status.IsCompleted) ? " is completed." : " is failed."));
        }
Hope this help. Stay tuned for the next part...

Categories:   .NET ASP.NET C# | Tip(s)
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | RSS


Rename and Trim MP3 Tag

Have you ever download file from internet which has many wrong tag name and some annoying number on them? Well, I have a small solution for your problem. This is a small program i wrote to overcome that problem. It'll trim the first prefix letters and delete the wrong MP3 Tag from your mp3

What you need is a library called TagLib from http://developer.novell.com/wiki/index.php/TagLib_Sharp, a library allows you to modify id3 tag, download it and put it on your bin folder.

1. I put a code to be invoked on button click event

 

private void button1_Click(object sender, EventArgs e)
  {
            FolderBrowserDialog dialog = new FolderBrowserDialog();
            dialog.ShowDialog();
            if (dialog.SelectedPath != "")
            {
                // I read number From textbox to get number of characters to be trim
                int numOfPrefix = Int32.Parse(textBox1.Text);
            }
  }

 

2. I read file names from the folder i've selected. Then I substring the folder path + number of the letters i want to remove.

 

String[] x = Directory.GetFiles(dialog.SelectedPath);
                char[] charset = dialog.SelectedPath.ToCharArray();
                List theFileSet = new List();
                foreach (String a in x)
                {
                    String thechar = a;
                    // Num of prefix is number of letter i want to remove
                    thechar = thechar.Substring(charset.Length + 1 + numOfPrefix);
                    
                    // Add it to list
                    theFileSet.Add(dialog.SelectedPath + "\\" + thechar);
                }

                // x array is the original file names, y array is the modified file names
                String[] y = theFileSet.ToArray();

 

3. I use move operation to rename the filename, and i modifile id3 tag by using tagLib library (don't forget to add the reference)

for (int i = 0; i < x.Length; i++)
                {       
                    // Rename filename by Move operation
                    System.IO.File.Move(x[i], y[i]);

                    // Begin Tag modification
                    TagLib.File f = TagLib.File.Create(x[i]);

                    // I remove album artists, album, genres and composers
                    f.Tag.AlbumArtists = null;
                    f.Tag.Album = "";
                    f.Tag.Genres = null;
                    f.Tag.Composers = null;

                    // Don't forget to save the file Tag
                    f.Save();
                }

Ok that's all the operation in this program. I'll post the full code in my personal blog, don't forget to check out my personal blog. I put what i learn on my blog http://cmmadnat.posterous.com/mp3-renamer-and-id3-tag-editor Thank you, see ya!

Categories:   .NET ASP.NET C#
Actions:   E-mail | del.icio.us | Permalink | Comments (1) | RSS


Event in ASP.NET AJAX lib Explained

In ASP.NET AJAX lib, there're 2 important types of events, event for Component (Sys.Component) and event for DOM Element.

Let's revise our old knowledge first.

Component (So, its derived class obtains these characteristics)

  • Has to relation with DOM at all.
  • Has no UI representation (not like Control (derived from Component base class) that has).
  • Encapsulates client codes to reuse it across applications *** this is the purpose of Component that exceeds the original DOM elements. In AJAX lib, DOM elements are represent(encapsulate and enrich, indeed) by Sys.UI.Control base class, which actually derive from Sys.Component. So, Component is not Control, but its super class. Component means AJAX lib can manage that things. Some components you wouldn't see with bare eyes (like timer,etc.). Did you get it?
  • Has Handler (cross-browser) that can bind with client object events.
  • Implement Sys.IDisposable.
  • Can raise the propertyChanged notification event when object property changed.
  • You can access events of that Component using get_ and set_ events.

To manage events of Component, we use Sys.EventHandlerList class. It's a dictionary of client events for a component, with event names as keys and the associated handlers as values. It has 3 methods addHandler, clearHandler, and getHandler. For example, when binding event to Component:

   add_tick: function(handler) {
this.get_events().addHandler('tick', handler); }, remove_tick: function(handler) {
this.get_events().removeHandler('tick', handler); }

 this means anything (any class,whatever) that's derived from Component base class. The very important thing is here:

var h = this.get_events().getHandler('tick');
if (h) h(this, Sys.EventArgs.Empty);

This will execute the handler function h. Remember that this handler belongs this Component. For example, Handler 'tick' (this handler) might be the event that is specified from a page developer outside our authority. We, a component developer, may not know this handler at all. He may want to do some special effects presenting to the user on top of UI layer after the time ticked. Page developer doesn't have an idea what's inside our Component too, he just uses it cluelessly.

On the other hand, event for DOM element, when we attach it to that element we call it event binding to DOM element. For example, I bind 'click' event to my button on the page. When it's clicked, it'll do my handler function. Don't forget that, DOM is not the same as Component. It's just a small subset. Here, it is (complete list of its methods): http://msdn.microsoft.com/en-us/library/bb383775.aspx. I think you're familiar with it, no need to explain much:

//register handler for click event on the expand control
$addHandler(yourElement, 'click', yourHandlerFunction);

$clearHandlers(yourElement);

Note that if this.get_element() that you love returns AJAX lib wrapped up DOM element. So, you can attach it an event like this example as well.

Stay tuned for the very near article. Thanks.

Categories:   AJAX Technology | Javascript | Tip(s)
Actions:   E-mail | del.icio.us | Permalink | Comments (2) | RSS


 

Tag Cloud