Combine differently sized JPEGs with jpegtran - panoramas

I've successfully used jpegtran to combine JPEGs of the same size (512x512) using the method described in this stackoverflow answer: https://stackoverflow.com/a/29615714/2364680
These are tiled JPEGs from the internet that make a 360 panorama when combined. As I said, the 512x512 images combined perfectly with jpegtran; however, I realized that some of the tiles that make up the panorama are 256x256 and need to be doubled in size when combined with the other tiles in order to form the panorama (in the 2D form of an equirectangular projection).
Simply put, I need to know if jpegtran can losslessly combine two JPEGs of different sizes -- for instance, if I can losslessly double the resolution of a 256x256 tile and then combine it with another 512x512 tile.
I know this can be done through reencoding, but I'm asking if it can be done totally losslessly. Thanks.

Not currently, no. We'd need the following:
Lossless crop - long supported
SmartScale - note that this is not ITU JPEG compliant, will change the pixel size of macroblocks, and will fail with many decoders.
Ability to change macroblock size partway through a file. My guess is that SmartScale doesn't support this, but some newer image/video compression formats do.
Supporting software - not currently available. I tested the latest available at this time, JPEG-9e, which cannot append JPEGs of differing SmartScale ratios / macroblock sizes
Here's what I came up with given that jpegtran's -crop, -scale and -drop operations cannot be combined:
#start with two images
#512x512.jpg - 64x64 macroblocks
#256x256.jpg - 32x32 macroblocks
#uncrop 2x1x using libjpeg7+ to give us space for later.
#out.jpg resolution is 1024x512, 128x64 macroblocks
jpegtran -crop 1024x512+0+0 -outfile out.jpg 512x512.jpg
#upscale the 256px image to 512x512 using libjpeg8+'s SmartScale
#Note: Does not change image width/height in macroblocks!
#Note: Only changes width/height of macroblocks!
#upscale.jpg is 512x512 but still 32x32 macroblocks
jpegtran -scale 8/4 -outfile upscale.jpg 256x256.jpg
#drop in upscale.jpg on the right half of the output image.
jpegtran -drop +512+0 upscale.jpg -outfile out.jpg out.jpg
However, the last command fails with: "Bogus virtual array access" which is the string for JERR_BAD_VIRTUAL_ACCESS error thrown by jpeg-9e/jmemmgr.c line 857.
It fails because end_row > ptr->rows_in_array where rows_in_array is 32 macroblocks and end_row reaches 33 macroblocks - the first macroblock row not present in upscale.jpg
jpegtran is expecting a 512x512 pixel image to be 64x64 macroblocks using the destination image macroblock size, so halfway through upscale.jpg it runs out of source macroblocks and walks off the end of the image. If we patched libjpeg to use the correct macroblock size, we'd need some way to encode into the file that the size of macroblocks has changed, but I'm not sure how that would be done.

Related

How to use lcms2 to check for out-of-gamut colors?

I'm converting images with embedded ICC profiles to the sRGB color space using LittleCMS. I want to efficiently detect when this conversion is lossy due to the image containing pixels that are out-of-gamut for the sRGB (e.g. the image is using Display P3 and contains saturated colors).
Note that I don't want to merely check if the embedded profile has a wide gamut, because the image pixels may not be taking advantage of its full gamut, and still fit in sRGB.
I know there's cmsSetAlarmCodes, but this seems like it could cause false positives, because there's nothing stopping the image from actually containing the same color that I set for my alarm color. Does LCMS have some out of band signal for this?
Another approach that comes to my mind is applying conversion twice: to sRGB and then back to the original color space, and checking how lossy it was. But that more than doubles processing time. Is there a more efficient way?

Converting DICOM images into nrrd images preserving pixel spacing

I am trying to convert a series of MRI DICOM images (.dcm) into .nnrd format. I found this guide for doing it in 3D slicer and I managed to do it. The problem is that the new nrrd image that is created has lost the pixel spacing of the original DICOM image.
In the additional settings, while converting the image, I also unticked the "Compress" box but the problem is still there. For instance, checking the two images (original .dcm and new .nrrd) in Imagej I get this:
The two images (nrrd on the left and dcm on the right) where I highlighted the old and the new pixel spacing
Anyone knows how to solve this? Any other alternative (that preserves the pixel spacing) is well accepted.
Thanks a lot in advance,
Tommaso
Your DICOM file is corrupted. Some mandatory tags are missing (e.g. 20,37, Image Orientation (Patient)). Therefore Slicer cannot properly compute the spacing. It even shows you in "Dicom Browser" window the following warning (after clicking Examine button): "Reference image in series does not contain geometry information. Please use caution".
If you cannot fix original images, you can apply manually all required spacing elements. Either do it in Slicer before exporting (Module Volumes -> Volume Information), or you can fix nrrd files themselves. Open them in your favorite text editor:
NRRD0004
# Complete NRRD file format specification at:
# http://teem.sourceforge.net/nrrd/format.html
type: short
dimension: 3
space: left-posterior-superior
sizes: 512 512 1
space directions: (1,0,0) (0,1,0) (0,0,1)
kinds: domain domain domain
endian: little
encoding: gzip
space origin: (0,0,0)
You have to update this line:
space directions: (0.507812,0,0) (0,0.507812,0) (0,0,4)
The true spacing are under tags 0028,0030 (X and Y) and 0018,0050 (Z).

QPainter::drawImage prints different size than QImage::save and print from Photoshop

I'm scaling a QImage, currently as so (I understand there may be more elegant ways):
img.setDotsPerMeterX(img.dotsPerMeterX() * 2);
img.setDotsPerMeterY(img.dotsPerMeterY() * 2);
When I save:
img.save("c:\\users\\me\\desktop\\test.jpg");
and subsequently open and print the image from Photoshop, it is, as expected, half of the physical size of the same image without the scaling applied.
However, when I simply print the scaled QImage, directly from code:
myQPainter.drawImage(0,0,img);
the image prints at the original physical size - not scaled to half the physical size.
I'm using the same printer in each case; and, as far as I can tell, the settings are consistent between both print cases.
Am I misunderstanding something? The end goal is to successfully scale and print the scaled image directly from code.
If we look at the documentation for setDotsPerMeterX it states: -
Together with dotsPerMeterY(), this number defines the intended scale and aspect ratio of the image, and determines the scale at which QPainter will draw graphics on the image. It does not change the scale or aspect ratio of the image when it is rendered on other paint devices.
I expect that the reason for the latter case being the original size is that the image has already been drawn before the call to the functions to set the dots per meter. Or alternatively, set the dots per meter on the original image, before loading its content.
In contrast, when saving, it appears that the device which you save to is copying the values you have set for the dots per meter on the image, then drawing to that device.
I would expect creating a second QImage, setting its dots per meter, then copying from the original to that second image, it would achieve the result you're looking for. Alternatively, you may just be able to set the dots per meter before loading the content on the original QImage.

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).

Editing size of image without loosing its quality and dimensions

I have a image with size of 5760 x 3840px with size of 1.14mb. But I would like to reduce its size to 200 kb by not changing the dimensions of the image. How Could I do this using photoshop? Please help me
This answer is based on a large format file size that has a resolution of 300 dpi. If the image is 5760 x 3840, your canvas size will be 19.2 x 12.8. in order to not "reduce" the dimension (printable area) you are going o have to reduce the image size [ALT + CTRL/CMD + I] and then reduce the resolution from there.
At 300 DPI:
At 72 DPI:
This reduction in resolution can decrease the file size dramatically, There is a chance of artifacts, but as you are starting at a high resolution the compression algorithms will smooth it out to almost non-existent.
NOW... If you are starting at 72dpi and you are looking for a good way to generate a lower file size for the web, your best bet may be to do a Safe for web option [ALT + CTRL/CMD + SHIFT + S] and generat a .jpg, .gif or a .png based on the final needs of the file. If it is an photograph with a lot of colors, I would go .jpg. If you have a lot of areas of solid color (logo perhaps) I would go with .png or .gif.
The Save for Web option allows you to see, side by side, the results of the export BEFORE going through the save process. it also allows you to alter the settings of the save process to dial in your results. best of all, it gives you a pretty good preview of the expected file size.
Either way this should help you save that larger file size for future use.

Resources