StretchDIBits seems slow, Is there any API faster? - gdi

I want to draw a dib on to a HDC, the same size.
I am using :
des and src are of the same size.
::StretchDIBits(hdc,
des.left,des.top,des.right - des.left,des.bottom - des.top,
src.left, GetHeight() - src.bottom, src.right - src.left,src.bottom - src.top,
m_pImg->accessPixels(),m_pImg->getInfo(), DIB_RGB_COLORS, SRCCOPY);
but I find it is slow, because the des size is the same, I just need to copy the dib onto a dc.
Is there any method faster than StretchDIBits?
just as
StretchBlt (slow) vs Bitblt.(faster)
StretchDIBits (slow ) vs ?(faster)

The speed difference comes from doing any necessary color conversion in addition to the generality necessary to handle the stretching (even if your target size is the same as your source size).
If you're just drawing the image just once, then I think function you're looking for is SetDIBitsToDevice.
If you care about the speed because you're drawing the same DIB multiple times, then you can improve performance by copying the DIB to a compatible memory DC once, and then BitBlt-ing from the memory DC to the screen (or printer) each time you need it. Use CreateCompatibleDC to create the memory DC, and then use StretchDIBits or SetDIBitsToDevice to get the image on it. After that, you can use BitBlt directly. You might also look into using a DIBSECTION, which gives a compromise in performance between a true DIB and a compatible DC.

Related

How to avoid strange structure artifacts in scaled images?

I create a big image stitched out of many single microscope images.
Suddenly, (after several month of working properly) the stitched overview images became blurry and they are containing strange structural artefacts like askew lines (not the rectangulars, they are because of not perfect stitching)
If I open any particular tile in full size, they are not blurry and the artefacts are hardly observable. (Consider, the image below is already 4x scaled)
The overview image is created manually by scaling each tile using QImage::scaled and copying all of them to the corresponding region in the big image. I'm not using opencv's stitching.
I assume, this happens because of image contents, because most if the overview images are ok.
The question is, how can I avoid such hardly observable artefacts to become very clearly visible after scaling? Is there some means in OpenCV or QImage?
Is there any algorithms to find out, if image content could lead to such effect for defined scale-factor?
Many thanks in advance!
Are you sure the camera is calibrated properly? That the lightning is uniform? Is the lens clear? Do you have electrical components that interfere with the camera connection?
If you add image frames of photos on a uniform material (or non-uniform material, moved randomly for significant time), the resultant integrated image should be completely uniform.
If your produced image is not uniform, especially if you get systematic noise (like the apparent sinusoidal noise in the provided pictures), write a calibration function that transforms image -> calibrated image.
Filtering in Fourier space is another way to filter out the noise but considering that the image is rotated you will lose precision, and you'll be cutting off components of the real signal, too. The following empiric method will reduce the noise in your particular case significantly:
ground_output: composite image with per-pixel sum of >10 frames (more is better) over uniform material (e.g. excited slab of phosphorus)
ground_input: the average(or sqrt(sum of px^2)) in ground_output
calib_image: ground_input /(per px) ground_output. Saved for the session, or persistent in a file (important: ensure no lossy compression! (jpeg)).
work_input: the images to work on
work_output = work_input *(per px) calib_image: images calibrated for systematic noise.
If you can't create a perfect ground_input target such as having a uniform material on hand, do not worry too much. If you move any material uniformly (or randomly) for enough time, it will act as a uniform material in this case (think of a blurred photo).
This method has the added advantage of calibrating solitary faulty pixels that ccd cameras have (eg NormalPixel.value(signal)).
If you want to have more fun you can always fit the calibration function to something more complex than a zero-intercept line (steps 3. and 5.).
I suggest scaling the image with some other software to verify if the artifacts are in fact caused by Qt or are inherent in the image you've captured.
The askew lines look a lot like analog tv interference, or CCTV noise induced by 50 or 60 Hz power lines running alongside the signal cable or some other electrical interference on the signal.
If the image distortion is caused by signal interference then you can try to mitigate it by moving the signal lines away from whatever could be the source of the problem, or fit something to try to filter the noise (baluns for example).

Image Plots components

At page 136 of the user manual of ILNumerics CTP (RCh), there is a mention to an Image Plot, in the "future section".
Is this the name of a new coming component similar two the TwoDMode of a 3D surface in a PlotCube, but optimized for 2D rendering or so? Could you describe its use case/functionalities?
(I would appreciate to have the possibility to quickly draw image plots (like Matlab imagesc) even with GDI backend. Currently GDI is to slow to render 700x700 ILSurface objects in a PlotCube with TwoDMode=true.)
imagesc - as you noticed - can be realized by a common surface plot in 2D mode. A 'real' imagesc plot would hardly do anything else. If the GDI renderer is too slow on your hardware, I'd suggest to
switch to an OpenGL driver, or
decrease the size of the rendering output, or
prevent from transparent colors (Wireframe or Fill), or
decrease the number of grid columns / rows in the surface
Note, the GDI renderer is mostly provided as fallback for OpenGL and for offscreen rendering. It utilizes decent scanline / z-buffer rendering. But naturally, it is not able to deliver the same speed as hardware accelerated OpenGL driver. However, 700x700 output should work even with GDI - on recent hardware (at least a couple of frames per second, I would guess).

Use an Image or using the graphic function for 2D game dev?

I'm trying to write a simple game that has some dogs and cats move around. Now my dogs, cats is the read and blue rectangle, I need to make them more pretty and now is 2 options for me:
Using an Image.
Draw them by some graphic class.
But I not sure what should I choose!
If use Image, I must draw some (the object can animate). But it make thing simple.
Use graphic function give me more power (like in case there more than just dog and cat, OO will help me alot). But I will make my barin hurt.
And the the most important is which is faster?
BTW I'm using Qt.
I'd most definitely use a bitmap.
Rendering a bitmap image is usually faster because it can be fully cached in memory unless it's large (which it shouldn't be, in your case). The underlying mechanics would simply involve a blazingly-fast memcpy (or the like) once it's been read from the disk.
Drawing a dog using vector graphics would incur a large overhead in terms of performance due to function calls, math/transformations, and would end up effectively needing more memory than a bitmap.

Why does OpenGL provide support for mipmaps but not integral images?

I realize both mipmaps and integral images have the problem that the resulting pixel value is not the integral of an arbitrary polygon in original texture space. Integrating over axisaligned rectangle in texture coordinates using integral images requires 4 texture lookups. Using mipmaps, opengl interpolates across the 4 adjacent pixel values in the mipmap so also 4 memory lookups. Using an integral image you need less memory (no extra preresized images, only an integral image instead of the original) and no level determination. Of course this can be implemented through shaders, but why was the (now being deprecated) fixed function pipeline ever designed with mipmap support and no integral image support?
Using an integral image you need less memory
I very much doubt that this statement is true
From what I understand the values of an integral image can get quite large, therefore requiring floating point representation which will use a lot more space than a typical 24bit mipmap (mipmaps only double the size of an image) and/or be less precise and create noise during interpolation. Also floating point images were not really used that often with the fixed function pipeline and GPUs may have been a lot slower with floating point images.
If you would use integers for the picture then the bit-depth required for the integral image would rise unreasonably high (bitdepth = extents+8 for a white image which means a 256x256 image would need a bit-depth of 264bit per color channel) with higher resolution images.
but why was the (now being deprecated) fixed function pipeline ever designed with mipmap support and no integral image support?
Because the access and interpolation of mipmaps could be built as rather simple hardwired circuits. Ever wondered, why texture dimensions had to be powers of two? To implement mipmaping calculations as a series of bit shifts and additions. Also accessing the neighbouring elements in a gaussian pyramid requires less memory accesses than evaluating the integral. And there's your main problem: Fillrate, i.e. video memory bandwidth, always has been a bottleneck of GPUs.

GDI+ 's Amazing decode speed, and terrible draw speed!

Thanks for answers,Actually I am not puzzled about draw 1024*768 pixels is slower than 100* 100 pixels... It is so simple a logic..
Which made me puzzled is that DrawImage's interpolation algorithm may be very slow, while there exists lots of better algorithm, and its decoder seems can decode from a jpg with a certain resolution, it is really cool, I search for sometime but do not find any free lib to do this...
It is really strange!
I add the following code into on Paint method. c:\1.jpg is 5M jpg file, about 4000*3000
//--------------------------------------------------------------
HDC hdc = pDC->GetSafeHdc();
bitmap = Bitmap::FromFile(L"c:\\1.jpg",true);
Graphics graphics(hdc);
graphics.SetInterpolationMode( InterpolationModeNearestNeighbor );
graphics.DrawImage(bitmap,0,0,200,200);
The above is really fast! even real time! I don't think decode a 5m JPG can be that fast!
//--------------------------------------------------------------
HDC hdc = pDC->GetSafeHdc();
bitmap = Bitmap::FromFile(L"c:\\1.jpg",true);
Graphics graphics(hdc);
graphics.SetInterpolationMode( InterpolationModeNearestNeighbor );
graphics.DrawImage(bitmap,0,0,2000,2000);
The above code become really slow
//--------------------------------------------------------------
If I add Bitmap = Bitmap::FromFile(L"c:\1.jpg", true); // into construct
leave
Graphics graphics(hdc);
graphics.SetInterpolationMode( InterpolationModeNearestNeighbor );
graphics.DrawImage(bitmap,0,0,2000,2000);
in OnPaint method,
The code is still a bit slow~~~
//------------------------------------------------------------------
Comparing with decoding, the drawImage Process is really slow...
Why and How did they do that? Did Microsoft pay the men taking charge of decoder double salary than the men taking charge of writing drawingImage?
So, what you're really wondering is why
graphics.DrawImage(bitmap,0,0,200,200);
is faster than
graphics.DrawImage(bitmap,0,0,2000,2000);
Correct?
Well, the fact that you are drawing 100 times more pixels in the second case could have something to do with it.
You don't need to decode JPGs if you're scaling down by a factor of 8. JPG images consist of blocks of 8 by 8 pixels, DCT-transformed. The average value of this block is the 0,0 coefficient of the DCT. So, scaling down a factor of 8 is merely a matter of throwing away all other components. Scaling down even further (eg 4000->200) is just a matter of scaling down from 4000 to 500, and then scaling normally from 500 to 200 pixels.
It could be possible that the decoding is deferred until needed. That's why it is so fast.
Maybe on the 200x200 case GDI+ only decodes enough blocks to paint 200x200 and on 2000x2000 they decodes more.
Graphic routines always contains some obscure optimizations, you could never know.
Maybe Reflector will tell you?
Just a guess, but could you try drawing with 4000x3000 or 2000x1500? Perhaps the fact that 4000 and 3000 are divisible by 200 is speeding up the whole and 3000 not being divisible by 200 slows it down (although this really would be weird).
Generally, do some profiling or time measurement. If 2000x2000 is about 100 times slower than 200x200, everything is okay. And don't bother if 2000x2000 is too slow. If your screen is at 1024x768, you can't see the whole image, so you better pick the part of the image that is visible on the screen and draw it, 1024x768 is 5 times faster than 2000x2000.

Resources