Let's say i have a 100000x100000 1 bit (K channel) tiff with a dpi of 2000 and i want to downscale this to a dpi of 200. My resulting image would be 10000x10000 image. Does this mean that every 10 bits in the 1 bit image correspond to 1 pixel in the new image? By the way, i am using libtiff and reading the 1 bit tiff with tiffreadscanline. Thanks!
That means every 100 bits in the 1 bit image correspond to 1 pixel in the new image. You'd need to average the value over 10x10 1bit pixel area. For smoother greyscales, you'd better average over n bits where n is the bit depth of your target pixel, overlying the calculated area partially with neighbor areas (16x16px squares 10x10px apart, so their borders overlay, for a smooth 8-bit grayscale.)
It is important to understand why you want to downscale (because of output medium or because of file size?). As SF pointed out, colors/grayscale are somewhat interchangeable with resolution. If it is only about file size losless/lossy compression is also worth to look at..
The other thing is to understand a bit of the characteristics of your source image. For instance, if the source image is rasterized (as for newspaper images) you may get akward patterns because the dot-matrix is messed up. I have once tried to restore an old news-paper image, and I found it a lot of work. I ended up converting it to gray scale first before enhancing the image.
I suggest to experiment a bit with VIPS or Irfanview to find the best results (i.e. what is the effect of a certain resampling algorithm on your image quality). The reason for these programs (over i.e. Photoshop) is that you can experiment with GUI/command line while being aware of name/parameters of the algorithms behind it. With VIPS you can control most if not all parameters.
[Edit]
TiffDump (supplied with LibTiff binaries) is a valuable source of information. It will tell you about byte ordering etc. What I did was to start with a known image. For instance, LibTIFF.NET comes with many test images, including b&w (some with 0=black, some with 1=black). [/Edit]
Related
I have images of around 2000 X 2000 pixels. The objects that I am trying to identify are of smaller sizes (typically around 100 X 100 pixels), but there are lot of them.
I don't want to resize the input images, apply object detection and rescale the output back to the original size. The reason for this is I have very few images to work with and I would prefer cropping (which would lead to multiple training instances per image) over resizing to smaller size (this would give me 1 input image per original image).
Is there a sophisticated way or cropping and reassembling images for object detection, especially at the time of inference on test images?
For training, I suppose I would just take out the random crops, and use those for training. But for testing, I want to know if there is a specific way of cropping the test image, applying object detection and combining the results back to get the output for the original large image.
I guess using several (I've never tried) networks simultaneously is a choice, for you, using 4*4 (500+50 * 500+50) with respect to each 1*1), then reassembling at the output stage, (probably with NMS at the border since you mentioned the target is dense).
But it's weird.
You know one insight in detection with high resolution images is altering the backbone with "U" shape shortcut, which solves some problems without resize the images. Refer U-Net.
"NVIDIA researchers have successfully trained a neural network to find
these jagged edges and perform high-quality anti-aliasing by
determining the best color for each pixel, and then apply proper
colors to create smoother edges and improve image quality. This
technique is known as Deep Learning Super Sample (DLSS). DLSS is like
an “Ultra AA” mode-- it provides the highest quality anti-aliasing
with fewer artifacts than other types of anti-aliasing.
DLSS requires a training set of full resolution frames of the aliased
images that use one sample per pixel to act as a baseline for
training. Another full resolution set of frames with at least 64
samples per pixel acts as the reference that DLSS aims to achieve."
https://developer.nvidia.com/rtx/ngx
At first I thought of sample as it is used in graphics, an intersection of channel and a pixel. But that really doesn't make any sense in this context, going from 1 channel to 64 channels ?
So I am thinking it is sample as in the statistics term but I don't understand how a static image could come up with 64 variations to compare to? Even going from FHD to 4K UHD is only 4 times the amount of pixels. Trying to parse that second paragraph I really can't make any sense of it.
16 bits × RGBA equals 64 samples per pixel maybe? They say at least, so higher accuracy could take as much as 32 bits × RGBA or 128 samples per pixel for doubles.
Does any one know which is going to be better for a browser loading time between these two options:
background-image:url('1by1px.png');
or
background-image:url('10by10px.png');
A 1px by 1px semi transparent png repeated for the div. Or a larger one say 10px by 10px.
There must be some kind of looping that has to be done to display the repeated image in the browser, and so I wondered if the image which is 1px by 1px causes alot of looping to get the image displayed that it may in fact be less speedy than a larger dimensioned image with less looping?
Of course the counter argument is image size is smaller for 1by1 compared to 10by10, but doesn't mean its better to be smaller because looping many times might not scale as good as looping a large image size slightly less often.
Does any know more about which would be better and how browsers handle situations like this?
When not repeating the background image, the time required to render depends on only the final scaled image, not the original one.
The image in a file is compressed as PNG format, but after being loaded by browser, it is in RGBA bitmap format (4 bytes for a pixel). When repeating a background, (let say on Intel x86), the native code of browser would use REP MOVSD to move the bitmap data from RAM to video memory (this is standard sequence, might be different on various implementations of graphics driver or specific GPU).
Assume that the dimensions of the HTML DIV which contains the background would be 100x100.
For the only-1 pixel image: the browser programme has to exec 10 thousand 'REP MOVSD' instructions.
For the 10x10 image: with each repeated image, the browser programme has to exec 'REP MOVSD' only 10 times (1 time calling to 'REP MOVSD' can render 1 pixel line (pixel row) of the image). So in this case, the number of 'REP MOVSD' instructions executed would be only 10x100 times (10 times in 1 image, 100 repeated images). This takes totally 1 thousand 'REP MOVSD'.
Therefore, the final background based on the bigger image would be rendered faster.
More notes:
The above explanation doesn't mean the performance is exactly 10 times better for the 10x10 image. A 'REP MOVSD' (with CX=9999 for example) is only 1 single CPU instruction but still requires 9999x4 bytes to be transfered through data bus. If using 9999 simple 'MOV's, that much of data still have to go thru' data bus, however, CPU has to execute 9998 instructions more. A more clever browser would create a pre-rendered bitmap for the background with replicated images; so each time it needs to transfer to video memory, it needs just only 100 'REP MOVSD' (100 is the number of pixel rows in the final background, assumed above) instead of 10 thousand or 1 thousand.
I agree with Paul answer.
I did few rough test with Google Chrome developer tool recently.
I used different size of semi-transparent png images on top of a background image and use page paint time to see how long do it take to refresh the screen.
Here is the result:
Time to refresh without -webkit-transform hack (rounded):
2x2 image : 65-160ms
10x10 image: 60-150ms
100x100 image: 55-135ms
1000x1000 image: 55-130ms
Time to refresh with -webkit-transform hack (rounded):
2x2 image : 40-120ms
10x10 image: 30-90ms
100x100 image: 30-90ms
1000x1000 image: 30-90ms
Just like what Paul said, bigger image is take shorter time to load(refresh), than smaller image.
But, it seem it is getting less effective after the image getting bigger than 10px. I don't see much difference between 100x100 and 1000x1000.
In my opinion, an huge image won't give you a noticeable result, and it might increase the loading time. So, I think any size around 10 - 100 is good enough for performance and loading time.
But still, different image might have different result, I think you should test your site with page paint time tool in Google Chrome developer tool for accurate result.
Apologies in advance, but this isn't really a photoshop question. Rather, I'm trying to come up with something that is convincing but exploits the compression and features of the gif format as best as possible to produce the smallest possible file for the animation.
Some constraints:
It needs to be at least 20 or 30 frames. I've tried with fewer (and since they're largely uncompressable 15 frames is half the size of 30, generally speaking)
Size needs to be no less than about 256x192
It doesn't need to be color though, nor even full grayscale. I've seen convincing stills with as few as about 16 grays
It can have a pattern, but not one that is instantly obvious to the human eye. If someone takes a single frame and after a minute or two can spot the pattern (which makes it compressable?) that's ok
Frames 2 through n can use quite a bit of alpha, but when I started using big horizontal stripes of alpha, it was instantly noticeable to my eyes. So you don't get to rack up a bunch of RLE with the easy cheat.
All of the above and still needs to look good at 30-33ms frame speed. No variable speed or relying on anything significantly faster than that.
Also acceptable: an apng that complies with the above constraints. Possibly even mpeg, if you can come up with that (I'm ignorant of how the DCT does its magic).
Ideally I could get something down in the 250kbyte range, but I'd settle for anything significantly smaller than the 9 meg monstrosity I cooked up last week.
Oh, and one last thing: obviously I don't expect anyone to supply the graphic for me. I'm just looking for some trick(s) that will let me get there myself eventually.
This is a very interesting question.
Static (random noise) by its nature is actually highly incompressible. Information theory says that true noise is basically incompressible, and the more patterns something contains the more compressible it becomes (to the point of a solid line of 1's or 0's being perfectly compressible.
The ideal would be to create a true noise generator (just random numbers), but that doesn't help within the constraints of your problem.
The best thing I can think of is storing a number of small tiles of static and displaying them in staggered fashion to prevent the eye catching on to any patterns. Aside from that, you won't have much luck compressing this beyond 256 x 192 x 20 / 2 or about 500 kilobytes ( assuming 20 frames with resolution of 256 x 192, using 4 bit color depth ).
Simply encoding your animated gif in 16 color mode should get you to that point.
Well old but still unanswered answer (not checked anyway)
so create the NoSignal image data
If it is not obvious how read this:
NoSignal in asm and C++
encode into gif
Had played with it a bit so I used resolution 320x240, the lowest bit resolution usable is 3 bit per pixel. Lower does not look good. Single global palette only (obvious) here 300KB example
[Notes]
if this is just for some app then generate the image on the run it is really just few lines of code see that linked answer in bullet #1
Yes, you can achieve that with a lossy GIF compression, or rather a specifically rigged compressor that outputs noisy LZW stream.
A best-case scenario for LZW compression is to output X pixels, then X+1 pixels, then X+2 pixels, etc. It's easy to make that noisy.
Try screwing up the gfc_lookup function to (almost) always return longest dictionary item and compress series of noisy frames with it:
https://github.com/pornel/giflossy/blob/master/src/gifwrite.c#L270
Not easily normally. Good randomness (high entropy) by definition does not compress well. Having it greyscale may help, but not much.
If you want to do this on a web page and you have (some) control, you can always write a very small bit of JS to help... if you can do this, then you can do the following:
Create a gif about 1.5x the size you need with high-entropy static.
Set the clipping to the size you want.
Then you randomly move it around by changing the starting offset.
As long as your offsets are a decent distance away from one another (and don't repeat patterns) it is usually difficult to discern it as movement, and it looks truly like static.
I did this trick about 20 years ago on an Amiga to emulate static on a limited-memory demo, and it worked remarkably well... it also does not require fast low-level code as all was done by changing offsets and the co-processor bitblit-ed the rest.
I was wondering if anyone has done any tests with background images. We normally create a background that repeats at least in one direction (x or y or both).
Example
Let's say we have a gradient background that repeats in X direction. Gradient height is 400px. We have several possibilities. We can create as small image as possible (1 pixel width and 400 pixels high) or we can create a larger image with 400 pixels height.
Observation
Since gradient is 400 pixels high we probably won't choose GIF format, because it can only store 256 adaptive colours. Maybe that's enaough if our gradient is subtle, since it doesn't have that many, but otherwise we'll probably rather store image as a 24-bit PNG image to preserve complete gradient detail.
Dilemma
Should we create an image of 1×400 px size that will be repeated n times horizontally or should we create an image of 100×400 px size to speed up rendering in the browser and have a larger image file size.
So. Image size vs. rendering speed? Which one wins? Anyone cares to test this? With regards to browser rendering speed and possible small image redraw flickering...
The rendering speed is the bottleneck here, since bigger tiles can be put into the browser's cache.
I've actually tried this for the major browsers, and at least some of them rendered noticeably slow on very small tiles.
So if increasing the bitmap size does not result in ridiculously big file sizes, I would definately go with that. Test it yourself and see. (Remember to include IE6, as still many people are stuck with it).
You might be able to strike a good balance between bitmap size and file size, but in general I'd try 50x400, 100x400, 200x400 and even 400x400 pixels.
I found out that there may be a huge difference in the rendering performance of the browser, if you have a background-image with width of 1px and repeating it. It's better to have a background-image with slightly larger dimensions. So a image with a width of 100px performs much better in the browser. This especially comes into play when you use a repeated background-image in a draggable layer on your website. The drag-performance is pretty bad with an often-repeated background-image.
I'd like to point out that for the cost of sending down an extra few rows (1-2 only example here) .8k - 1.6kb (if you can get away with 8-bit) more like 2.4kb - 4.0kb for 24bit
2 pixel columns more means the required iterations required to blit the background in is cut down to 1/3 for up to 1.6kb (8-bit) or 4kb (24bit)
even 1 extra column halves the blitting required down to half the element width.
If the background's done in less than a second for a 56.6k modem I reckon it's lean enough.
If small dimensions of an image have a negative impact on rendering, I'm sure any decent browser would blit the image internally a few times before tiling.
That said, I tend not to use 1 pixel image dimensions, so I can see the image clearly without resizing it. PNG compression is good enough to handle this at very little cost to file size, in most situations.
I'd put money on the bottleneck being the image download rather than the rendering engine doing the tiling, so go for the 1 pixel wide option.
Also the 24-bit PNG is redundant since you're still only getting 8 bits per channel (red, green and blue).
I generally prefer to go in between, 1pixel wide will probably make your gradient seem a bit unclear but you can do something like 5pixel width which gives enough room to the gradient to maintain consistency and clarity across the page.. but I would suggest you can add more patterns and images to a single image and then use background positioning(css sprites) to position them because download a single image of say 50kb would take less time comapared to 5 40kb images since the browser makes fewer requests to the server...
I have not benchmarked this but I'd bet that on most modern computers the rendering won't be an issue whereas you always want to save on on the image download time. I often go for the 1px type of graphics.