Comments (10)
This isn't really code I am familiar with (whilst we now maintain imager, we obviously didn't write much of the code base, and do not use all of its functionality). That said- from what I can see the display function expects images to be in a RGB colour space, and sRGB is just close enough that visually it still looks reasonable. So, I don't think there is actually a bug here, it is just being used incorrectly when trying ti directly display HSV. That's my quick assessment- I might be wrong.
The display function itself is pretty low level (Cimg itself) so any bugs there should be communicated to the Cimg team (since we just use their header for imager).
from imager.
Although now I realise I cannot even display the images like this on my Mac version. It complains I don't have the X11 package installed (which I don't, but that isn't needed anymore and isn't available for R now). How did you get round that?
from imager.
It complains I don't have the X11 package installed (which I don't, but that isn't needed anymore and isn't available for R now). How did you get round that?
I don't have an x11-package installed either. Are there any additional potential packages that might be at play here? However, bear in mind that at least the github-source of the package lists X11
as a system-dep:
Line 25 in 6586883
Which bears the question of how I am satisfying this dep; because I sure don't recall setting it up - nor can I find it anywhere ¯\_(ツ)_/¯
I have created a small R-project that reproduces the issue on my end. Additionally, it contains the image in question - just in case that uploading to and downloading from a github-issue alters it (it shouldn't, but I've seen weirder shit). All packages installed during installation of imager
are recorded in the lockfile and can be restored via renv
:
https://github.com/Gewerd-Strauss/reprex_clean_imager
from imager.
So, I don't think there is actually a bug here, it is just being used incorrectly when trying ti directly display HSV. That's my quick assessment- I might be wrong.
In that case, a couple of things:
- Can I trust the numerical array resulting from
im <- imager::load.image(path)
im_srgb_to_rgb <- imager::sRGBtoRGB(im)
im_rgb_to_hsv <- imager::RGBtoHSV(im_srgb_to_rgb)
(disregarding the small info-loss between srgb and rgb?). Does im_rgb_to_hsv
actually contain proper hsv-formatted data?
-
If I can't trust the hsv-data, I assume my only options are to either
- implement a very slow translational alg in R myself to arrive at valid hsv-data?
- process in RGB and just hope the issue doesn't compound
?
-
Are you aware of any other packages that can convert srgb/rgb<>hsv?
-
Do you know which format
imager::load.image
loads in? It seems to be either sRGB or RGB, but I am not sure.
from imager.
I don't think the issue is in the load, but rather the display- that function only meaningfully displays RBG data. Again, this is just from having a cursory look at the lower level calls being made- the display itself is really handled by the Cimg library not imager.
from imager.
@Gewerd-Strauss what @asgr says seems to be right to me too. You are giving HSV values to display
, which is interpreting them as RGB, so you don't get what you expect.
I think it's safe to trust the HSV data. Given how the underlying CImg library is used so widely in many products, and this being is one of the core functions that the library would perform, you'd expect it to perform it correctly. If you want to double-check you can compare a couple of individual HSV pixel values in im_rgb_to_hsv
against the RGB values in im_srgb_to_rgb
, and check with an external converter tool (first google hit shows https://www.rapidtables.com/convert/color/rgb-to-hsv.html) that the values correspond.
Alternatively you can alter the HSV values in a meaningful way, the display the HSV->RGB result and check that it makes sense. For example, you do im_rgb_to_hsv[1:3000,,1,3] = 0
and check that the first half of your image is blacked out. Or something along those lines.
from imager.
Alternatively you can alter the HSV values in a meaningful way, the display the HSV->RGB result and check that it makes sense. For example, you do
im_rgb_to_hsv[1:3000,,1,3] = 0
and check that the first half of your image is blacked out. Or something along those lines.
I did so today, and am happy to confirm that the experiment seems to confirm that conversion is indeed valid. Or to be more precise - it is visually blacked out.
Unfortunately, there seem to still be some issues:
Let's inspect the original image im
. Let's take an arbitrary pixel (2674,3872), color space: sRGB
:
I use GIMP to retrieve this info. GIMP uses its built-in sRGB space.
Now, let's see what imager loads; im <- imager::load.image(path)
returns object im
, which should contain pixels in sRGB-colorspace.
For r im[2674,3872,1,X]
, we get in sRGB:
Flipping the coordinates gives similar values:
If we inspect the RGB-colors after sRGB>RGB-conversion:
Flipped:
This means that GIMP either
- internally loads the image in sRGB, but reports pixels in RGB instead of sRGB. In this case, the data reported by GIMP should line up with
im_srgb_to_rgb[]
. - internally loads the image in sRGB and also reports in sRGB (and the description in the GIMP-GUI is a misnomer). In this case, the data should line up with
im
.
Neither of those would line up even remotely on scales of either 0-1 or 0-255 with where they should be.
Taking an arbitrary yellow pixel gives the same issue:
We get a similar issue; in that values don't seem to line up.
I did so for a couple more pixels, but don't see the need to paste another 30 cropped screenshots in here.
The hex-codes identified by GIMP are also returned by various other means when inspecting these pixels. Either GIMP lies, along with MS Paint, Autohotkey 1 & 2, and virtually every other utility I could find that can report pixel info; or the color-conversion of the R-package is somewhat fishy.
To me, the values reported make little sense, and don't line up with colors and hex codes reported by any other program or converter.
This leaves me utterly confused, because now basically nothing seems to make any sense. I kinda hope that I am just completely unaware of something here.
There are further oddities that don't make too much sense imo, a curious example:
path <- r"(D:\Dokumente neu\Repositories\clean_imager\example.jpg)"
im <- imager::load.image(path) ## load image
im_srgb_to_rgb <- imager::sRGBtoRGB(im) ## convert srgb to rgb
im_rgb_to_hsv <- imager::RGBtoHSV(im_srgb_to_rgb) ## convert to hsv
im_rgb_to_hsv_altered3 <- im_rgb_to_hsv ## create copy
im_rgb_to_hsv_altered3[1:3000,1:4000,1,3] = 1 ## alter val
im_hsv_to_rgb_altered3 <- imager::HSVtoRGB(im_rgb_to_hsv_altered3) ## convert back to RGB
imager::display(im_hsv_to_rgb_altered3)
The image is 6000x4000 pixels large. Thus, im_rgb_to_hsv_altered3[1:3000,1:4000,1,3] = 1
should only modify half the image - the left half, to be specific.
However, this is the image we get:
Given the ranges used 1:3000
& 1:4000
, how are all pixels of the image altered? For reference, here is the HSV-image before modifying pixels, via imager::display(imager::HSVtoRGB(im_rgb_to_hsv))
:
So yea. I have no clue what the hell is going on. ¯\_(ツ)_/¯
from imager.
Without getting into the colour space conversion issue (you might need to raise questions there with Cimg directly), the jpeg I inspect is identical between imager::load and jpeg::readJPEG. Note readJPEG uses a different structure where the x/y dimensions are swapped (neither is wrong, since matrices we display matrices in a transposed sense anyway).
test_imager = imager::load.image('~/Downloads/309751145-e22f4886-1473-4925-977e-86dbbe5ab1db.jpg')
test_imager[2996,3261,1,]
[1] 0.3019608 0.2980392 0.2823529
test_base = readJPEG('~/Downloads/309751145-e22f4886-1473-4925-977e-86dbbe5ab1db.jpg')
test_base[3261,2996,]
[1] 0.3019608 0.2980392 0.2823529
readJPEG does warn that other programs flip the ink scales. There are also many ways other programs might remap RGB (for reasons of dynamic range). Both imager::load and jpeg::readJPEG access the raw data as encoded in the file.
from imager.
@Gewerd-Strauss I think your coordinates are also wrong? The arbitrary pixel with RGB = (46, 125, 96) is not (2674,3872) but (2686, 3881) (0-indexed). When reading the image as read by imager
(add 1, since R is 1-based) you get:
> im[2687,3882,1,]
[1] 0.1803922 0.4901961 0.3764706
which is the RGB value you expect.
Regarding the display, while I'm not completely sure, I'm half-guessing that display
might be doing its own internal colour adjustment when displaying colours so that you get to see something, so I wouldn't give it too much attention.
Like @asgr says, I don't see an issue here.
from imager.
After a good amount of fiddling and more reading, I have successfully resolved the "issue", and will thus close this issue.
Thank you for the various explanations.
from imager.
Related Issues (14)
- Now you can submit imager 0.42.19 HOT 1
- Compilation error when trying to upgrade to imager v.0.45.8 HOT 7
- Suggestion: Loading subset of image as defined by coordinate set only HOT 1
- Build failure with errors related to standard integer types (uint*_t) in tiff function signatures. HOT 3
- Question: What are the loss-rate during the `SRGBtoRGB()` and `RGBtoHSV()`-conversions HOT 1
- Imager on Windows fails its own CRAN Package Checks
- Install error in R 4.3.3 HOT 2
- Interactively grabbing multiple points from an image HOT 2
- checking whether package ‘imager’ can be installed ... WARNING Found the following significant warnings: ../inst/include/CImg.h:29015:48: warning: ‘%s’ directive argument is null [-Wformat-overflow=] ../inst/include/CImg.h:58256:45: warning: ‘%s’ directive argument is null [-Wformat-truncation=] HOT 2
- Question: Can I update the vignette, there seems to be a fair bit missing HOT 1
- set_omp_num_threads compiling error (utils.cpp) HOT 5
- Problem using load.video() from paths with spaces HOT 1
- bug HOT 6
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from imager.