30 September 2012

Python code for non rigid registration using opencv and numpy

Here is a simple python code for registering two images. The transform is non-rigid. The error metric is sum of squared difference. Code is very simple, does not handle physical spacing. Main aim was to get hands dirty of numpy/scipy, python, opencv cv2 interface etc.
One practical tip for registration: if all else fails, smooth heavily the motion fields ;-)

##################################################
"""
Created on Sun Jan 15 10:41:19 2012

@author: vsk
"""
import sys, os, cv2, numpy, matplotlib, pylab
def SSD_Register(static_image, moving_image):
    IMG_BLUR = 11;
    ITER = 200;
    TIME_STEP = 0.00010;
    SMOOTH = 1.0;
    K_SIZE = 11;
   
    # Create float versions of all images
    registered_image = numpy.empty(static_image.shape, dtype=numpy.float32);  
    static_image_float = numpy.empty(static_image.shape, dtype=numpy.float32);
    mov_image_float = numpy.empty(static_image.shape, dtype=numpy.float32);

    for i in range(static_image.shape[0]):
        for j in range(static_image.shape[1]):
            static_image_float[i,j] = static_image[i,j];
            mov_image_float[i,j] = moving_image[i,j];
                       
    static_image_blur = cv2.GaussianBlur(static_image_float,(IMG_BLUR,IMG_BLUR), 1.20);
    mov_image_float = cv2.GaussianBlur(mov_image_float, (IMG_BLUR,IMG_BLUR), 1.20);
   
    difference_image = numpy.empty(static_image.shape, dtype = numpy.float32);
    # Space for motion field
    x_field = numpy.empty(static_image.shape, dtype=numpy.float32);
    y_field = numpy.empty(static_image.shape, dtype=numpy.float32);
    for i in range(x_field.shape[0]):
        for j in range(x_field.shape[1]):
            x_field[i,j] = j;
            y_field[i,j] = i;
           
    x_field_update = numpy.empty_like(x_field);
    y_field_update = numpy.empty_like(y_field);
    # Gradient image
    grad_x = numpy.empty_like(x_field_update);
    grad_y = numpy.empty_like(x_field_update);
   
    grad_x = cv2.Sobel(mov_image_float, cv2.CV_32FC1, 1, 0);
    grad_y = cv2.Sobel(mov_image_float, cv2.CV_32FC1, 0, 1);
    grad_x_resampled = numpy.copy(grad_x);
    grad_y_resampled = numpy.copy(grad_y);
    # registration iterations begin
   
    for i in range(x_field.shape[0]):
        for j in range(x_field.shape[1]):
            registered_image[i,j] = mov_image_float[i,j];
           
    difference_image = registered_image - static_image_float;
    print(numpy.sum(numpy.abs(difference_image))),
    ssd_err = numpy.zeros((ITER,1));
    for i in range(ITER):
    #    print i,
        difference_image = registered_image - static_image_float;
        #print(numpy.max(difference_image)),
        #print(numpy.min(difference_image))
    #    print(numpy.sum(numpy.abs(difference_image))),
        ssd_err[i]= numpy.sum(numpy.abs(difference_image));
        x_field_update = TIME_STEP*difference_image*grad_x_resampled;
        y_field_update = TIME_STEP*difference_image*grad_y_resampled;

        x_field_update = cv2.GaussianBlur(x_field_update, (K_SIZE, K_SIZE), 2.5);
        y_field_update = cv2.GaussianBlur(y_field_update, (K_SIZE, K_SIZE), 2.5);
    #    print(numpy.max(y_field_update))
        x_field = x_field - x_field_update;
        y_field = y_field - y_field_update;

        registered_image = cv2.remap(mov_image_float, x_field, y_field, cv2.INTER_CUBIC);
        grad_x_resampled = cv2.remap(grad_x, x_field, y_field, cv2.INTER_CUBIC);
        grad_y_resampled = cv2.remap(grad_y, x_field, y_field, cv2.INTER_CUBIC);
    print('')
    #pylab.imshow(registered_image); pylab.show(); pylab.gray()
    print(numpy.sum(numpy.abs(difference_image)))
    # display section
    display_image = numpy.copy(static_image);
    for i in range(x_field.shape[0]):
        for j in range(x_field.shape[1]):
            display_image[i,j] = registered_image[i,j];

#     cv2.namedWindow('Registered');
#     cv2.imshow("Registered", display_image);
#    
#     cv2.namedWindow('Final');
#     cv2.imshow("Final", moving_image);
#
#     cv2.namedWindow('Initial');
#     cv2.imshow("Initial", static_image);
#    
#     cv2.waitKey(-400)
#     cv2.destroyAllWindows();
#     pylab.plot(ssd_err)
#     pylab.show()
   
    pylab.subplot(131)
    pylab.imshow(static_image)
    frame = pylab.gca();
    frame.axes.get_xaxis().set_visible( False);
    frame.axes.get_yaxis().set_visible( False);
    pylab.title('Static Image');
   
    pylab.subplot(133)
    pylab.imshow(moving_image)
    frame = pylab.gca();
    frame.axes.get_xaxis().set_visible( False);
    frame.axes.get_yaxis().set_visible( False);
    pylab.title('Moving Image');
   
    pylab.subplot(132)
    pylab.imshow(registered_image),
    frame = pylab.gca();
    frame.axes.get_xaxis().set_visible( False);
    frame.axes.get_yaxis().set_visible( False);
    pylab.title('Registered Image');
   
    pylab.show()
    return (registered_image, ssd_err);
   
# ================  Read system arguments else generate images =================
if len(sys.argv) != 3:
    #print('Usage: static_image moving_image');
    static_im = numpy.zeros( (256, 256), dtype=numpy.ubyte);
    static_im[100:150, 100:150] = 100;

    x_field = numpy.empty(static_im.shape, dtype=numpy.float32);
    y_field = numpy.empty(static_im.shape, dtype=numpy.float32);
    for i in range(x_field.shape[0]):
        for j in range(x_field.shape[1]):
            x_field[i,j] = j + 12.00485;
            y_field[i,j] = i -  8.35;
   
    mov_im = numpy.zeros( (256, 256), dtype=numpy.ubyte);
    mov_im = cv2.remap(static_im, x_field, y_field, cv2.INTER_CUBIC);
    #mov_im[102:152, 100:150] = 100;
   
    SSD_Register(static_im, mov_im);  
else:
    static_image = cv2.imread(sys.argv[1], cv2.CV_LOAD_IMAGE_GRAYSCALE);
    moving_image = cv2.imread(sys.argv[2], cv2.CV_LOAD_IMAGE_GRAYSCALE)
    SSD_Register(static_image, moving_image)

10 February 2012

Regarding a trip to Puri temple

I have been meaning to write this since a long time, but never got around to do so. I visited the Jagannath Puri temple in 2008. It is 4 years now, but the visit remains extremely fresh in my mind. I had heard of crowds at Puri from relatives and friends before. The rudeness, greed and filthy language used by pandas was also indicated at. The advice given to me or rather us(since we were travelling in a group), was that avoid pandas at all costs, even if you have to listen to their entreaties which gradually become threats and end in abuse. This happens especially if there are females in the group, and fortunately or otherwise there was one in our group. As soon as we got down from the vehicle, we were surrounded. There was one guy who said who promised to take a sum which for his guidance. We made it clear that we are not interested in making some special puja(specially priced, if one may add). He agreed but obviously after entering premises, he said that prasad needs to be "bought", else visit is not possible. Needless to say, though we were not interested and wanted to get rid of him, the female of the group, who got a bit emotional with all the flowery language, agreed to buy some 150/- "basket". The puja coupon counter is another mess, manned by a fat scoundrel. Be as it may, after waiting for quite sometime, in which the scoundrel rudely asked the lady to pipe down, the panda came back with a basket. After entering the main temple, he asked each of us to put money as it was some custom. At this point we had enough and asked him to go away, which he did after muttering many things unpleasant. As I was moving along the queue for darshan, the panda thief inside, waved a large basket in front of me and shouted or demanded to put something inside. I said nothing but contented by just glaring at him. He kind of piped down. All in all, it was a filthy experience. 
It is sad that a temple and a holy place, where thousands come to pray, seek mental peace, succour, and relief, give their thanks, are treated so shabbily, abused, shoved and made to undergo such pain. Also, it is all the more surprising because the Puri temple's administrative board has some King as a member. Clearly, someone is snoozing. It is high time that the pandas be given the same treatment as thugees were given by the British. One may think that I am over-reacting, but I have decided not enter the temple again until I hear that things have improved. The pandas should realise that they are playing with fire in treating the devotees in this fashion. It is sad that no one is Odisha is interested in improving the situation.

Mahabhoj

मन्नू भंडारी द्वारा लिखित "महाभोज" पढ़ रहा हूँ। बहुत मोटी किताब नहीं है। कहानी का विषय है राजनीति। सारांश कुछ ऐसी है। किसी एक छोटे से गाँव में एक हरिजन समाजसेवक का लाश मिलने पर सरकार और विपक्षी नेता, दोनों इस "मौके" का फायदा उठाना चाहते हैं। कारण है कि इस घटना के कुछ ही दिनों बाद चुनाव है। वैसे तो है मामूली चुनाव लेकिन विपक्षी नेता इसी से अपना "नव निर्माण" करना चाहते हैं, और ये भी स्वाभाविक है की सरकारी दल, जिसमे कुछ नेता असंतुष्ट हैं,  इतनी आसानी से हारने वाली नहीं है। अब तक तो आधी ही पढ़ी है, लेकिन इतना तो समझ में आ ही गया है कि चुनाव में कोई भी जीते, असली में हारने वाले तो गाँव वाले ही हैं। इसलिए कह रहा हूँ कि कहानी बहुत ही सहज और स्वाभाविक रूप में लिखी गयी है। विभिन्न नेताओं का ऐसा सहज चरित्रांकन, बिना एक शब्द व्यर्थ किये, बहुत अच्छा लगा। ऐसा नहीं लगता है कि ये कोई कहानी है, बल्कि राजनीती के भीतरी एवं बाहरी चालबाज़ी का आँखों देखा हाल है।
खरीदिये और पढ़िए!

14 January 2012

Sony Ericsson Elm quick review

This is a quick review of the Sony Elm mobile cellphone.
Motivation and Decision!
The reason for the purchase was that I was looking for a cellphone within Rs. 8,000-10,000, with reasonable camera performance. I was tempted by LG and especially Samsung offerings. Since I have a very positive experience with Samsung E2232, I had decided upon Samsung Galaxy Y, which is a cheaper version of the more pricey ones of the same name. I was not specifically looking for Android phones or touchscreen phones. I am slightly wary of the touchscreen technology coming at too low a price; I guess that any company has to maintain its margin and will cut down on quality if pushed too hard. Now, all the reviews for Samsung were great except for a few which said that the camera was barely passable. I was also not looking for high megapixel, 3 would be more than enough. Sadly, moronic customers push the companies toward megapixel wars leading to degradation of images, or maybe the companies attract morons by such number games. However, I hesitated after reading the poor quality images. Then, I chanced upon the Sony Ericsson Elm. On  paper it seemed great; a Sony Ericsson product with decent reviews. I also saw some sample images at a website. Seemed reasonable to me for a phone costing 8000 or so. So I bought it.

General Comments
As far as looks go, this is fairly good. It is very conventional, no scratching or touching anywhere. The keypads are good, I played some games(pre-loaded) without worrying about damaging the pad. I would say that, this is about the only thing which I have positive to say about this overpriced brick. The phone itself is very slow. I never thought I would pay much attention to the themes, but the utter dullness and the available themes is galling. The sound quality is miserable, or to be honest maybe i expected better, since i was not paying for touchscreen and Android, I thought that I was getting better hardware.
Photos!
Ah, this is what I bought the phone for?! 

No, certainly not! This is bright sunshine! The hopeless quality is immediately apparent. Based on this short experience of 1 week, I think that I made a wrong choice. My general suggestion is that if you want a camera, buy one and if you want a phone, buy one with such features as you wish. Do not mix and match both, at least not for anything costing less than 25,000. At that price or a bit more, you may get an entry level DSLR nowadays. However, if you do feel like donating money by spending it on such a combo, while I do not know which to recommend, I most certainly which NOT to go for: Sony Ericsson Elm!

30 October 2011

Samsung E2232 Mobile phone review

This is the probably the second time I am writing a review for an electronic product. There were not a lot of reviews for this particular model when I was looking for reviews. I was looking for a phone <= 2500 INR, with dual SIM, Music player and FM radio. Camera was optional. I considered some equivalent Nokia models Nokia X1-01, I went to a shop and the body was was not very good. The keypads felt a bit annoying. Another option was Nokia C1-02, the quality is also not to my expectation. Keypad takes a hit. So, I bought this E2232 because of the almost feature for feature match with Nokia C1-02, including poor camera quality! I got E2232+2GB microSD card for 2400/- in Bangalore, 10 or so days back(pre-Diwali Saturday). The Nokia phone itself was more expensive; card would cost more pushing the expenditure to 2700 or so.

In the package, I got: handset, charger, headphone and battery. 2GB was from shop's side. Pluses of E2232 in my opinion after some usage:
  • Bluetooth, FM radio, Music player, all there
  • Menu is quite ok, this is my first dual SIM phone. using both the SIMS and configuring them is a breeze. One can associate a profile with each SIM. That means one can have spearate ringtone, colour, theme etc for each SIM. All the contacts appear together in the address book; I see this as an advantage. For identification, each contact is marked with the respective SIM icon.
  • There is a separate button for the music player. I did not think this to be a big deal initially, but i can see that this is an advantage. As FM does not have dedicated button, I have to traverse a bit of the menu to change settings(channel, volume, recording).
  • Recording from FM, I recorded a nice violin piece which was being broadcast on AIR Sangeet Sammelan. Recording is fine. 
  • It comes with few Indian languages: Hindi, Tamil, Kannada and possibly Telugu, apart from English. I have not tested any of these.
As the world is not an idea place, there are a few minuses as well for this product.
  • my biggest grouse is the body quality, especially the back portion. It comes out with minor falls. You might ask if this is worse than the above mentioned Nokias; probably not. I noticed this only when the phone took a fall; the back and battery came out. I had to reset the timing and date again. Very annoying and anxiety inducing.
  • Average battery? Now I am not sure about this because my earlier phone was Motorola model, bought maybe 4+ years back. The battery is incredible, it has taken falls and also direct throws to the ground. It may need a steel tipped bullet to destroy this thing. Compared to that, the E2232 is a energy sucker. Since this was newly bought, I was using the music or radio or Bluetooth transfer very heavily. 
  • Extremely poor camera, but I do not mind. It was expected. I wish they removed the camera and put that money into the body. My planned use for the camera is to photograph the (principally IT) monkeys on bikes who ride on the pavement, to cleverly evade traffic, and upload to some photosharing website. Maybe, it might sear their thick hides and might stop doing it. But that is an aside.
  • Suspect keyboard; it kind of feels flimsy but let us see how it lasts. I am not a heavy SMS user.
  • Pathetic quality of the headphone/earphone set. Now, again one cant buy everything at 2200 or so, but this earpiece is junk. It keeps on slipping, or so it feels. Maybe Koreans have smaller ears(no joke/racism), but to me I have to keep my head like the lady in the clip to keep the earphone from slipping. Planning to get a headphone set cover the ear. Again, I wish the camera gets removed and something gets added here.
More as I use more. A sample pic will be posted presently.
Go for this phone after verifying Nokia's build is worse; otherwise this is fine(for the time being).
27/11/2011
Photo as promised. Although  taken in indoor condition under normal condition, the quality is hopeless. What more for 2250/-....


14 November 2010

20 October 2010

India passport portal disarray

I recently applied for the renewal of my passport. The application process has been considerably revamped but there still exist some hiccups. Still considering the sorry state of affairs which existed as recent as 5 years ago, this is heaven sent. One must pay obeisance to the "babus" and ministers who could agree to the change. Considering the state of affairs in India, this seems like divine intervention.
However, all is NOT well. For online application of passport, the link is in this page for applicants living within Bangalore and Chandigarh. One clicks on the "How to Apply" link in the left side of the above page and it takes us to a page which has more information on the application process. All this is fine. There is also a "Login/Register" link for new users. For a number of days, I have been seeing that after entering the username, password and the "captcha", the site seems to have "lost" the security certificate. This, in Firefox, results in a security warning. I have to add an exception to reach the page. Most of the time the page does not load. The page is maintained by none other than India's premier software merchant Tata Consultancy Services. I feel no need to say more. If a maintainer cannot maintain a security certificate for such an important portal in order, I shudder to think of the security of the database. Such a shoddy maintenance of an essential portal is only possible in the IT "superpower" that is India. Let us not lose hope though. Some countries are worse. Let us sing "jai Ho" and "all is well".
Also, one can apparently check the status of one's passport application here. The file number which we are supposed to enter is a letter followed by 6 digits. Somehow, mine is much bigger. Of course, who cares.

17 September 2010

Online book buy review

I have been purchasing a fair amount of books online. This is not a comprehensive review of online sellers in India. Till now, I have tried 4: flipkart, infibeam, bookadda and nbcindia. Of these, Flipkart is undoubtedly best; it beats others hands down on terms of service. If they show that a book is available, you can be pretty much sure that it indeed is. Their price is generally below the marked price or equal. They deliver for free anywhere in India for orders above Rs. 100/-. This last bit is true for all the others. Their customer support is very good and answer queries about pricing promptly. I have made purchases more than or close to Rs. 3000/- in the last few months. I have also bought some cheap VCDs. Full marks to the team.

Next, I would rate Infibeam. The price of books is generally lesser than that of Flipkart. Their service is also pretty good. I suspect that their inventory management can do with some improvement because it has happened that the book is shown as available but after the order has been placed, I get an email from the customer support saying that they could not complete the order. Refunding has been generally prompt. Customer service is not terrific but adequate. Sometimes, one has to act as the “annoyed customer” to get response. They sell both old as well as new books. I wish it were clearer if the book being purchased is old or new! This is well worth a wait if one is not in a terrible hurry to get books. They send books in inventory but take some time to acquire books and pass it on to you.

While looking for cheaper and cheaper deals online, i came across Bookadda. It has a user interface very similar to that of Flipkart. It looks so similar that I thought that Flipkart was operating a sister site. Also, the registered office is in Bangalore. The similarity with flipkart ends there. I put an order for a book which was not available with flipkart and infibeam. The book is “introduction to calculus and analysis: volume 1″ by Courant. Incidentally, flipkart showed the book as not available and infibeam does not show the indian edition to be available. However, bookadda shows this to be available. As nothing was moving after placing the order for a few days, I emailed customer support and got no response. I called up the local contact number and was told that I would be contacted in half an hour. My cell as well as landline numbers were taken. I often wonder what kind of miserable slugs become these call centre agents who promise all the time but deliver not a whit. Anyway, there was no call in half one or two hours. Generally, I do not like to pursue and pain people but this was annoying me. So I called up again and was told that the book was not available and I would get a refund. No refund status was forthcoming and I called up again to find out how long it would take. I have been promised a refund by today, I do not of course believe it. The amount is not high but nobody like the feeling of being hoodwinked. Personal opinion: GIVE ANOTHER CHANCE.

UPDATE (20/09/2010)

I got an email about 2 days from the customer care of bookadda expressing regret for being unable to complete their order and have also given a gift voucher worth 50/-. Not a tremendous amouunt but the gesture is appreciated. I could not update this earlier as I was travelling. Will give these guys another shot.

I placed an order with nbcindia last week. It is too early to say but I fear that it is headed the bookadda way. I hope not because there are some hindi books available there.


Update 25/09/2010

After calling nbcindia’s customer service, they informed me that of the two books I ordered, only one was available immediately. They were waiting for the other book. I do not know how long they would have waited if I had ot called them up. They gave their word to dispatch the available book and refund the amount for the other if the publisher did not get back to them that very day. Apparently, the publisher did not get back and they sent it by Aramex Courier that day. I got it in two days flat. The book which did not make it: “Manto ki Chuninda Kahaniyan”.

20 June 2010

Google commandline services

It seems to be a bit odd to be posting something in praise of Google on blogger; if anyone bothers to read this blog they might be forgiven if they accuse me of toadying up. Anyway, the big news is that Google has released Python based scripts to access and use a host of Google services. No wonder Google has consistently beaten the pants off its rivals. 

11 June 2010

OpenCV 2.1.0 and FFMPEG compilation solution

I had been recently struggling to compile OpenCV 2.1.0 with FFMPEG support on GNU/Linux. The problem was that the OpenCV CMake script fails to detect the important component of ffmpeg it needs; like avcodec, swscale, avformat. The more idiotic thing is that if one uses ccmake, the log is not visible. It is only after building that one sees that ffmpeg support is not there. One has to use cmake. Anyways, after doing cmake ../OpenCV-2.1.0, noted that config log said “ffmpeg 0″ and also put zeros against the above mentioned components of ffmpeg. Well, I knew that ffmpeg existed in all its components. I had also made a directory called ffmpeg in /usr/local/include and made symbolic links for the respective header files. Now it was a clear case of cmake being unable to find these, either because of poor CMakeLists.txt or the cmake itself. At this point, I did not want to dig into the innards of CMake; unlike autoconf it has an annoying tendency to hide information; for example where it searches for ffmpeg and such things. Such blackbox approach suits Ubuntu users no doubt. I tried parsing through the CMakeLists.txt and could not find anything that I could rectify. However, I did know that CMakeCache.txt contained the configured values. After that it was a matter of putting manually the include, lib paths and the linker flags in this for each of the ffmpeg components. After running cmake again, I could immediately see that ffmpeg components were recognised and ffmpeg was turned to 1. make happily started building cvcap_ffmpeg which meant that ffmpeg was actually being used. However, the build process croaked at 99% when trying to link to the actual libavcodec/libavformat and libswscale. Clearly, the linker links I had passed as a guess had not worked. Now, I did cmake again and passed -L/usr/local/lib and -Wl, -rpath,/usr/local/lib. Voila! the compilation was complete. I build a test program to read and write videos. All worked ok. This was a rough sketch of the compilation solution. I will post the details of the CMakeCache.txt in case someone is interested.