Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to achieve good sharpness with twain/emgu/open cv?

I am using an Epson Perfection V700 scanner and selecting the following options when scanning using their tool:

  • ICM Color correction (source: EPSON-Standard and target: sRGB)
  • Unsharp Mask (medium)

That produces this image:

Image from Epson Tool

Now my problem is this - I actually need to interact with this scanner using TWAIN .Net and when I do so, the image I get back is this:

TWAIN Scanned Image

Aside: I unselected the aforementioned two options and scanned again with the Epson and got a very similar image to what I get through TWAIN.

So I figure that perhaps these are post processing steps that I can do myself on the image (maybe they are done in the hardware somehow though, I don't know).

I am using EmguCV so first of all I created an extension method that applies the ICM (I struggled to find any documentation for this, so it is a bit of a guess and maybe I am wrong straight away but I got the information from here: The bitmap transform class and it seems to make a difference to the image):

public static Image<Bgr, TDepth> ApplyIcm<TDepth>(
    this Image<Bgr, TDepth> source,
    string sourceIcm,
    string targetIcm)
    where TDepth : new()
{
    var target = source.CopyBlank();

    using (source)
    {
        using (var b = source.Bitmap)
        {
            using (var memory = new MemoryStream())
            {
                b.Save(memory, ImageFormat.Bmp);
                memory.Position = 0;

                var bitmapImage = new BitmapImage();
                bitmapImage.BeginInit();
                bitmapImage.StreamSource = memory;
                bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
                bitmapImage.EndInit();

                var ccb = new ColorConvertedBitmap();
                ccb.BeginInit();
                ccb.Source = bitmapImage;

                ccb.SourceColorContext =
                    new ColorContext(new Uri(sourceIcm));

                ccb.DestinationColorContext =
                    new ColorContext(new Uri(targetIcm));

                ccb.EndInit();

                var encoder = new BmpBitmapEncoder();
                encoder.Frames.Add(BitmapFrame.Create(ccb));
                using (var ms = new MemoryStream())
                {                            
                    encoder.Save(ms);
                    target.Bitmap = new Bitmap(ms);
                }
            }
        }
    }

    return target;
}

Then I looked at that unsharpen thing and came across this question: How to sharpen an image in OpenCV? which says:

You use a gaussian smoothing filter and subtract the smoothed version from the original image

(I also checked this question to find out what the equivalent emgucv call is Why might EmguCV Gaussian blur not return identical results as OpenCV Gaussian blur?) and came up with this additional extension method:

public static Image<Bgr, TDepth> UnsharpMask<TDepth>(
    this Image<Bgr, TDepth> source,
    Size kernelSize,
    int kernelHoritonalStandardDeviation,
    int kernelVerticalStandardDeviation,
    double alpha,
    double beta,
    double gamma)
    where TDepth : new()
{

    Image<Bgr, TDepth> ret = source.CopyBlank();

    CvInvoke.cvSmooth(source,
                      ret,
                      SMOOTH_TYPE.CV_GAUSSIAN,
                      kernelSize.Width,
                      kernelSize.Height,
                      kernelHoritonalStandardDeviation,
                      kernelVerticalStandardDeviation);

    CvInvoke.cvAddWeighted(source, alpha, ret, beta, gamma, ret);

    return ret;
}

Now I call it like so:

string sourceIcm = @"C:\Windows\System32\spool\drivers\color\ewrgb18.icm";
string targetIcm = @"C:\Windows\System32\spool\drivers\color\ewsrgb.icm";

using(var im = new Image<Bgr, byte>("out.bmp"))
{
    using (var icmmed = im.ApplyIcm(sourceIcm, targetIcm))
    {
        using (var ret = icmmed.UnsharpMask(new Size(0, 0), 5, 5, 2.4, -1.5, 0))
        {
            ret.Save("ret.bmp");
        }
    }
}

and this is the result:

After my sharpening

Not very good! :-(

I have fiddled with the parameters endlessly but I just cannot work out how (or even if) I can achieve the same result as the Epson tool.

So, my question is:

Does anyone know if it is possible to achieve a result using opencv/emgucv (or even TWAIN - I had a look through the documentation for that and tried adjusting some of the capability parameters but I just made the image worse) that is similar in sharpness to the original image above or is there another technique I should try (could it be that I would need to know some details about the hardware itself in order to achieve correct sharpening)?

like image 664
kmp Avatar asked Jan 14 '13 15:01

kmp


People also ask

How do I increase sharpness in Opencv?

You use a Gaussian smoothing filter and subtract the smoothed version from the original image (in a weighted way so the values of a constant area remain constant). cv::GaussianBlur(frame, image, cv::Size(0, 0), 3); cv::addWeighted(frame, 1.5, image, -0.5, 0, image);

How do you sharpen a photo on a CV?

You can also sharpen an image with a 2D-convolution kernel. First define a custom 2D kernel, and then use the filter2D() function to apply the convolution operation to the image. In the code below, the 3×3 kernel defines a sharpening kernel. Check out this resource to learn more about commonly used kernels.

How do you increase the sharpness of an image in Python?

To sharpen an image in Python, we are required to make use of the filter2D() method. This method takes in several arguments, 3 of which are very important. The arguments to be passed in are as follows: src: This is the source image, i.e., the image that will undergo sharpening.


1 Answers

I think you should know how using WIA (Windows Image Acquisition) in your project, you may don't need to get access to hardware using opencv. WIA is used for integrating with webcams and scanners. Or, you can use TWAIN as you mentioned have a look at these examples they could by helpful for your project:

using WIA

and

using TWAIN

Concerning the sharpening, you can use opencv functionality at software level, as another choice to solve your problem

like image 168
Y.AL Avatar answered Oct 02 '22 12:10

Y.AL