Monday, March 11, 2013

Windows Azure does not scale - at all

Over the weekend the Windows Azure Portal was dead slow. While trying to get my invoices I got constant timeouts. So I opened a service ticket REG:113031010276036 .

Basically the issue fixed itself, because today the portal was usable again. But the supporter Frank was quite helpful and asked me what else he could do for me.

What was puzzling me for a while that I had all my invoices on the Trial subscription that I opened when testing Windows Azure. I got a expiry warning on the trial subscription so I had already opened a usage based subscription but this is untouched so far.

Azure is billing the trial subscription
As you can see all the billing is still on the trial subscription (in german "Kostenlose Testversion").

So I asked the guy from Azure support how I can switch the billing to the usage based subscription.

The answer was shocking. You cannot switch a subscription. You need a migration to a new subscription. And this is the current procedure.

"Here, the whole procedure, in order to achieve a migration or transfer.
 
IMPORTANT NOTICE: Please note that the transfer of feature preview (websites, virtual machines, etc.) and the SQL Reporting Service can not be performed, and these services must be created manually in the target subscription. Please note, if the
target subscription has a spending limit (MonetaryCap) this could be disabled during migration. If you remove this spending limit, you avoid that this target subscription is disabled.
 
First Please let us know if the target Subscription is empty because it is not possible to perform a migration in a non-empty subscription.Second Please ensure that the service administrator is equal on both subscriptions.
                
If you need to change the service administrator, you log in to the Management Portal (https://account.windowsazure.com/Subscriptions) with your WLID SourceSubscribtion
                     
select the subscription and click on "Modify Subscription Details". Then repeat this step for the target subscription.
 
Third Log into the management portal (https://manage.windowsazure.com) with service administrator Live ID or Co-Admin Live ID.
                
a) Click on SQL databases.
                
b) Click on Server.
                
c) Click on the name of the server you want to transfer.
                
d) Click on "Change Subscription".
                
e) Select the new subscription and close the wizard.
 
4th Transfer of Services
 
a) CDN Service Bus and Access Control and Caching namespaces and Media Services: Our technical department is responsible for this transfer. Please let us knowwhether you are using these services and send if the relative CDN Service Bus, Access Control namespace, media and caching services, so that we can carry out the transfer.This process can take up to 2 business days.
 
b) hosted services and storage accounts: We will carry out this transfer if the previous steps have been completed. Upon completion of this transfer, the Subscription source are automatically disabled. When this happens, please let us know whether we will then enable it again or remain disabled
 
Please contact us if you have completed step number 3 and send if the relative CDN Service Bus, Access Control namespace, media and caching services as described in step 4. "


WTF????

In other words they are telling me you cannot switch the subscription in Windows Azure. Because if you try you are guaranteed to go 2 days offline, you have to deal with 2 migration teams and install half of your solution yourself. Who wants to take that risk in a productive and running environment?

Nobody. So Windows Azure is scaling less than a netbook pc, because in my netbook  pc I can at least change the disk drive.

Unbelievable. If you had the illusion that Cloud Solutions scale with the demand of the customer, then this is the end with Microsoft Windows Azure.

This is no less than a total contradiction of any reason to use a cloud solution. 

If this is not a Knock Out criteria, what is?

Thursday, June 7, 2012

Digit Recognition with OpenCV (CPP Version)

This code is basically a cpp port inspired by the article "Simple Digit Recognition OCR in OpenCV-Python" . I even shamelessly stole his images. The handy thing of this example is the self test loop. This assures your thing is really working and ready to go on real world images.

The code has currently just on picture per digit to learn from and achieves an accuracy of 97% on the big image. To improve it you could add more samples for each number.

I tried to use as much the new cpp api as possible. At some point I still rely on the old c api. I am still trying to replace CvMat with cv::Mat and especially this loop

for (int n = 0; n < ImageSize; n++)
{
   trainData->data.fl[i * ImageSize + n] = outfile.data[n];
}

From my believe this is not the way things should be handled in an API but so far I found no other way.
Take the following images by clicking on them and downloading them to your images folder, which is in my case ../images relative to the location of the executable.


0.png
1.png
2.png
3.png
4.png
5.png
6.png
7.png
8.png
9.png
buchstaben.png
#include "opencv2/ml/ml.hpp">
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>

using namespace cv;
using namespace std;

const int train_samples = 1;
const int classes = 10;
const int sizex = 20;
const int sizey = 30;
const int ImageSize = sizex * sizey;
char pathToImages[] = "../images";

void PreProcessImage(Mat *inImage,Mat *outImage,int sizex, int sizey);
void LearnFromImages(CvMat* trainData, CvMat* trainClasses);
void RunSelfTest(KNearest& knn2);
void AnalyseImage(KNearest knearest);
/** @function main */
int main(int argc, char** argv)
{

 CvMat* trainData = cvCreateMat(classes * train_samples,ImageSize, CV_32FC1);
 CvMat* trainClasses = cvCreateMat(classes * train_samples, 1, CV_32FC1);

 namedWindow("single", CV_WINDOW_AUTOSIZE);
 namedWindow("all",CV_WINDOW_AUTOSIZE);

 LearnFromImages(trainData, trainClasses);

 KNearest knearest(trainData, trainClasses);

 RunSelfTest(knearest);

 cout << "losgehts\n";

 AnalyseImage(knearest);

 return 0;

}

void PreProcessImage(Mat *inImage,Mat *outImage,int sizex, int sizey)
{
 Mat grayImage,blurredImage,thresholdImage,contourImage,regionOfInterest;

 vector<vector<Point> > contours;

 cvtColor(*inImage,grayImage , COLOR_BGR2GRAY);

 GaussianBlur(grayImage, blurredImage, Size(5, 5), 2, 2);
 adaptiveThreshold(blurredImage, thresholdImage, 255, 1, 1, 11, 2);

 thresholdImage.copyTo(contourImage);

 findContours(contourImage, contours, RETR_LIST, CHAIN_APPROX_SIMPLE);

 int idx = 0;
 size_t area = 0;
 for (size_t i = 0; i < contours.size(); i++)
 {
  if (area < contours[i].size() )
  {
   idx = i;
   area = contours[i].size();
  }
 }

 Rect rec = boundingRect(contours[idx]);

 regionOfInterest = thresholdImage(rec);

 resize(regionOfInterest,*outImage, Size(sizex, sizey));

}

void LearnFromImages(CvMat* trainData, CvMat* trainClasses)
{
 Mat img;
 char file[255];
 for (int i = 0; i < classes; i++)
 {
  sprintf(file, "%s/%d.png", pathToImages, i);
  img = imread(file, 1);
  if (!img.data)
  {
    cout << "File " << file << " not found\n";
    exit(1);
  }
  Mat outfile;
  PreProcessImage(&img, &outfile, sizex, sizey);
  for (int n = 0; n < ImageSize; n++)
  {
   trainData->data.fl[i * ImageSize + n] = outfile.data[n];
  }
  trainClasses->data.fl[i] = i;
 }

}

void RunSelfTest(KNearest& knn2)
{
 Mat img;
 CvMat* sample2 = cvCreateMat(1, ImageSize, CV_32FC1);
 // SelfTest
 char file[255];
 int z = 0;
 while (z++ < 10)
 {
  int iSecret = rand() % 10;
  //cout << iSecret;
  sprintf(file, "%s/%d.png", pathToImages, iSecret);
  img = imread(file, 1);
  Mat stagedImage;
  PreProcessImage(&img, &stagedImage, sizex, sizey);
  for (int n = 0; n < ImageSize; n++)
  {
   sample2->data.fl[n] = stagedImage.data[n];
  }
  float detectedClass = knn2.find_nearest(sample2, 1);
  if (iSecret != (int) ((detectedClass)))
  {
   cout << "Falsch. Ist " << iSecret << " aber geraten ist "
     << (int) ((detectedClass));
   exit(1);
  }
  cout << "Richtig " << (int) ((detectedClass)) << "\n";
  imshow("single", img);
  waitKey(0);
 }

}

void AnalyseImage(KNearest knearest)
{

 CvMat* sample2 = cvCreateMat(1, ImageSize, CV_32FC1);

 Mat image, gray, blur, thresh;

 vector < vector<Point> > contours;
 image = imread("../images/buchstaben.png", 1);

 cvtColor(image, gray, COLOR_BGR2GRAY);
 GaussianBlur(gray, blur, Size(5, 5), 2, 2);
 adaptiveThreshold(blur, thresh, 255, 1, 1, 11, 2);
 findContours(thresh, contours, RETR_LIST, CHAIN_APPROX_SIMPLE);

 for (size_t i = 0; i < contours.size(); i++)
 {
  vector < Point > cnt = contours[i];
  if (contourArea(cnt) > 50)
  {
   Rect rec = boundingRect(cnt);
   if (rec.height > 28)
   {
    Mat roi = image(rec);
    Mat stagedImage;
    PreProcessImage(&roi, &stagedImage, sizex, sizey);
    for (int n = 0; n < ImageSize; n++)
    {
     sample2->data.fl[n] = stagedImage.data[n];
    }
    float result = knearest.find_nearest(sample2, 1);
    rectangle(image, Point(rec.x, rec.y),
      Point(rec.x + rec.width, rec.y + rec.height),
      Scalar(0, 0, 255), 2);

    imshow("all", image);
    cout << result << "\n";

    imshow("single", stagedImage);
    waitKey(0);
   }

  }

 }
}

Other Links:

K-Nearest Neighbors in OpenCV

digit recogntion using OpenCV on android

 

Monday, February 6, 2012

HTML: File input without the textbox

I wasted my day today trying to find a way to get a file input without this stupid textbox. Although there are several approaches none of them really works for all the browsers. Then I remembered I saw an example for the JQuery File Upload text box. So what I did is that I took their example and stripped it down to the relevant part. Now you can actually see, that they are some so strange stuff to get it to work. If you want to see the details, increase the opacity and remove the the overflow: hidden line.

You can fully style the button of your choice. In the JQuery File Upload example they have some nice JQuery UI Button style.




<html>

<head>
    <title>jQuery File Upload Example</title>
    <style type="text/css">
        .myfileupload-buttonbar input
        {
            position: absolute;
            top: 0;
            right: 0;
            margin: 0;
            border: solid transparent;
            border-width: 0 0 100px 200px;
            opacity: 0.0;
            filter: alpha(opacity=0);
            -o-transform: translate(250px, -50px) scale(1);
            -moz-transform: translate(-300px, 0) scale(4);
            direction: ltr;
            cursor: pointer;
        }
        .myui-button
        {
            position: relative;
            cursor: pointer;
            text-align: center;
            overflow: visible;
            background-color: red;
            overflow: hidden;
        }
    </style>
</head>
<body>
    <div id="fileupload" >
        <div class="myfileupload-buttonbar ">
            <label class="myui-button">
                <span >Add Files</span>
                <input id="file" type="file" name="files[]" />
            </label>
        </div>
    </div>
</body>
</html>

Thursday, August 18, 2011

How to fix Cygwin (make)

If you are using Eclipse on Windows, CDT and Cygwin you might see funny meaningful errors like:

make: *** target pattern contains no `%'.  Stop.    
make: *** multiple target patterns.  Stop.   

Some of them occur only after the second build, others pop up continuously.

This is most likely happening due to the fact that Cygwin make is broken with the current 3.81 release.

After wasting many hours I came to this announcement dating to 9 Jul 2006 related to make 3.81 from Christopher Faylor from Redhat on the Cygwin announce list:

Note that the --win32 command line option and "MAKE_MODE" environment
variable are no longer supported in Cygwin's make.  If you need to use a
Makefile which contains MS-DOS path names, then please use a MinGW
version of make.

Wikipedia describes Cygwin  as:

"Unix-like environment and command-line interface for Microsoft Windows."

In other this means that the make for Windows lacks Windows support.


This raises the following question:

Which user of  the Unix-like environment and command-line interface for Microsoft Windows. would ever miss the support  for MS-DOS aka Windows path names in the 2 most important development tool besides gcc?

I hope Chris is not thinking about shipping the next Redhat distro with a make that does not support Unix style path names. I mean this is fast way to increase your number of "fans" on Facebook but............

At least he is not only breaking it but also pointing in the right direction:
 
See: http://mingw.org/ for details on downloading a version of make
which understands MS-DOS path names.  Please! direct any questions about
the MinGW version of make to the appropriate MinGW mailing list.


Here you can download a version of mingw make.

I installs by default to C:\MinGW\bin\mingw32-make.exe

Then I just copied it to my cygwin\bin directory. After doing the only reasonable thing with the cygwin make, in other words deleting it, I just renamed mingw32-make.exe to make.exe and since then everything builds fine.

Update:

Robert Walker also pointed out that he offers some packages for download that contain all the necessary fixes.I tried 3.82-1 and its just works fine. Thanks!

Tuesday, August 17, 2010

Visual Studio 2010 COM-Interface Bugfest

"EnvDTE is an assembly-wrapped COM library containing the objects and members for Visual Studio core automation."

But unfortunately the implementation the the VS 2010 RTM version the library is pretty much unusable. Some methods like EnvDTE.Project.Delete() are not even implemented.


Others like EnvDTE._Solution.Remove(Project project) have buggy implementations. Removing a project with _Solution.Remove(Project project) will work, but when you try to add the same project from a different location using the _Solution.AddFromFile method you will end up with the error message "A project with that name is already opened in the solution". Once you removed it you have to restart Visual Studio if you ever want to be able to add the project to the solution.

As we speak the Visual Studio 2010 automation COM-Interface is not usable.

Friday, May 7, 2010

Workflow 4 Bugfest - no compensations

According to msdn

"Compensation in Windows Workflow Foundation (WF) is the mechanism by which previously completed work can be undone or compensated (following the logic defined by the application) when a subsequent failure occurs. This section describes how to use compensation in workflows."

Ok. Lets start with this very simple example:


But when you execute it you will find that...

Pufffff, it's gone!

None of our handlers is ever called. Our transaction is down the drain.

Hmm, maybe the transaction was not successful and this is the reason why none of handlers got called.

Lets try this:

But when you execute it you will find that...

the last message is "Do Transaction" then

Pufffffs, it's gone.

But on the other hand what happens if we delete the throw?

Then we see that the confirmed handler gets called at the end of our workflow.

This means:

If we use CompensableActivity and everything in our workflow completes successfully, the transaction gets "autocommitted". Otherwise its puffff gone.

But this behavior can be changed from outside.

Lets wrap the first example into one of this mysterious Try/Catch Block and let him handle the exception.



What we now see that all of a sudden our CancellationHandler gets called.

I am confused now.

First thing is that I would never expect my Compensation to just puffff. I mean I do serious thing in a compensation. This makes especially no sense to me, if a successful Compensation auto-commits and the end of the workflow. An even less if failed compensation calls the cancellationhadler only if it is wrapped into a Try/Catch block that handles the exception.

Update: In the MSDN Forum Steve Danielson investigated the issue and gave an excellent hint on the difference between C# Try/Catch and Workflow Try/Catch. This covers the behavior for CompensableAction as well

Workflow 4 Bugfest - The Exception handling bug

I currently dig into Workflow 4 (Final). After Workflow 3 really drove me nuts with its unbearable performance I was first positively impressed by Workflow 4. The designer as well as the workflow execution speed is there where I expect it to be.
I downloaded the samples and went through the basic shapes section. All fine here.

But my impression is about to change, as Workflow 4 seems to contain a number of serious bugs.

This becomes very evident if you look at the execution of the finally block in a try/catch activity.

According to msdn...

"The finally block is useful for cleaning up any resources allocated in the try block as well as running any code that must execute even if there is an exception. Control is always passed to the finally block regardless of how the try block exits."


The most simple form of a try-Catch Activity is this:

Please note that there is no Exception handler in the "Catches" section. I simply want the Exception to propagate, but before it does that I want to make sure my code block in finally is executed no matter what happens.

But if you now execute the code, you will find out that the code in our finally block never gets executed....

This will not change if you add an exception handler, that does not handle the specific exception.

To make things worse we will see, that even if we handle the specific exception and and want to rethrow it, our finally is never executed.

Actually the only time the finally gets executed in case of an exception is when the Exception is handled and not propagated.

This means:

In Workflow 4 you cannot propagate an exception and execute a finally block.

In other words:

You cannot use a finally block.

Update: In the MSDN Forum Steve Danielson gave an excellent hint on the difference between C# Try/Catch and Workflow Try/Catch.