tag:blogger.com,1999:blog-3704048544762396176.post630056694172698154..comments2023-06-01T16:38:21.578+02:00Comments on Coding Mess: Conversion of wavelength in nanometers to RGB in PythonR.L.http://www.blogger.com/profile/14598815714075739940noreply@blogger.comBlogger22125tag:blogger.com,1999:blog-3704048544762396176.post-39262774168888094352012-10-09T13:51:02.578+02:002012-10-09T13:51:02.578+02:00// wavelength to RGB(CvScalar)
CvScalar CHumanRbtF...// wavelength to RGB(CvScalar)<br />CvScalar CHumanRbtFollowBh::getTargetDistColor(double distRatio){<br /> // color difference according to the distance from human to target<br /> double w = (int)(400*distRatio) + 380;<br /><br /> if (w >= 380 && w < 440){<br /> mR = -(w - 440.) / (440. - 350.);<br /> mG = 0.0;<br /> mB = 1.0;<br /> }<br /> else if (w >= 440 && w < 490){<br /> mR = 0.0;<br /> mG = (w - 440.) / (490. - 440.);<br /> mB = 1.0;<br /> }<br /> else if( w >= 490 && w < 510){<br /> mR = 0.0;<br /> mG = 1.0;<br /> mB = -(w - 510.) / (510. - 490.);<br /> }<br /> else if( w >= 510 && w < 580){<br /> mR = (w - 510.) / (580. - 510.);<br /> mG = 1.0;<br /> mB = 0.0;<br /> }<br /> else if( w >= 580 && w < 645){<br /> mR = 1.0;<br /> mG = -(w - 645.) / (645. - 580.);<br /> mB = 0.0;<br /> }<br /> else if( w >= 645 && w <= 780){<br /> mR = 1.0;<br /> mG = 0.0;<br /> mB = 0.0;<br /> }<br /> else{<br /> mR = 0.0;<br /> mG = 0.0;<br /> mB = 0.0;<br /> }<br /><br /> // intensity correction<br /> if (w >= 380 && w < 420){<br /> mSSS = 0.3 + 0.7*(w - 380) / (420 - 380);<br /> }<br /> else if( w >= 420 && w <= 700){<br /> mSSS = 1.0;<br /> }<br /> else if( w > 700 && w <= 780){<br /> mSSS = 0.3 + 0.7*(780 - w) / (780 - 700);<br /> }<br /> else{<br /> mSSS = 0.0;<br /> }<br /><br /> // Adjust<br /> if (mR == 0.0){<br /> mR = 0.0;<br /> }<br /> else{<br /> mFinalR = (int)(255 * pow(mR*mSSS, 0.8));<br /> }<br /><br /> if (mG == 0.0){<br /> mG = 0.0;<br /> }<br /> else{<br /> mFinalG = (int)(255 * pow(mG*mSSS, 0.8));<br /> }<br /><br /> if (mB == 0.0){<br /> mB = 0.0;<br /> }<br /> else{<br /> mFinalB = (int)(255 * pow(mB*mSSS, 0.8));<br /> }<br /><br /><br /> m_TmpTargetColor = cvScalar(mFinalR, mFinalG, mFinalB);<br /><br /> return m_TmpTargetColor;<br />}<br /><br />worked better.. used Opencv too thanks!TheWritierhttps://www.blogger.com/profile/08960032634833182848noreply@blogger.comtag:blogger.com,1999:blog-3704048544762396176.post-12467915935916259122012-10-09T08:29:45.775+02:002012-10-09T08:29:45.775+02:00// wavelength to RGB(CvScalar)
CvScalar CHumanRbtF...// wavelength to RGB(CvScalar)<br />CvScalar CHumanRbtFollowBh::getTargetDistColor(double dist){<br /> // color difference according to the distance from human to target<br /> if (dist){<br /> return cvScalar(0,200,200);<br /> }<br /> else if(){<br /> return cvScalar(200,0,0);<br /> }<br /> else(){<br /> return cvScalar(100,0,0);<br /> }<br /><br /> double w = dist;<br /><br /> if (w >= 380 && w < 440){<br /> mR = -(w - 440.) / (440. - 350.);<br /> mG = 0.0;<br /> mB = 1.0;<br /> }<br /> else if w >= 440 && w < 490{<br /> mR = 0.0;<br /> mG = (w - 440.) / (490. - 440.);<br /> mB = 1.0;<br /> }<br /> else if( w >= 490 && w < 510){<br /> mR = 0.0;<br /> mG = 1.0;<br /> mB = -(w - 510.) / (510. - 490.);<br /> }<br /> else if( w >= 510 && w < 580){<br /> mR = (w - 510.) / (580. - 510.);<br /> mG = 1.0;<br /> mB = 0.0;<br /> }<br /> else if( w >= 580 && w < 645){<br /> mR = 1.0;<br /> mG = -(w - 645.) / (645. - 580.);<br /> mB = 0.0;<br /> }<br /><br /> else if( w >= 645 && w <= 780){<br /> mR = 1.0;<br /> mG = 0.0;<br /> mB = 0.0;<br /> }<br /> else{<br /> mR = 0.0;<br /> mG = 0.0;<br /> mB = 0.0;<br /> }<br /><br /><br />// intensity correction<br /> if (w >= 380 && w < 420){<br /> mSSS = 0.3 + 0.7*(w - 350) / (420 - 350);<br /> }<br /> else if( w >= 420 && w <= 700){<br /> mSSS = 1.0;<br /> }<br /> else if( w > 700 && w <= 780){<br /> mSSS = 0.3 + 0.7*(780 - w) / (780 - 700);<br /> }<br /> else{<br /> mSSS = 0.0;<br /> mSSS *= 255;<br /> }<br /><br /> m_TmpTargetColor = cvScalar((int)mSSS*mR, (int)mSSS*mG, (int)mSSS*mB);<br /><br /> return m_TmpTargetColor;<br />}<br /><br />C++ style of your code and OpenCV structure.. Thanks!Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-3704048544762396176.post-54821045097644311502011-07-15T12:52:14.221+02:002011-07-15T12:52:14.221+02:00Thanks for this!Thanks for this!Jannoreply@blogger.comtag:blogger.com,1999:blog-3704048544762396176.post-36642851859634809692010-06-30T11:01:53.695+02:002010-06-30T11:01:53.695+02:00Hello jonnyflash,
I'm glad you liked it. You d...Hello jonnyflash,<br />I'm glad you liked it. You don't have to credit this in any way. It is mostly not my effort anyway. <br />I often put link to source from the web into code comments and if you write about it somewhere on the web, a link here will be appreciated :-) <br />You should also consider crediting the autor of the algorithm, Dan Bruton, it is linked in the post.<br />R.L.R.L.https://www.blogger.com/profile/14598815714075739940noreply@blogger.comtag:blogger.com,1999:blog-3704048544762396176.post-50809905790793684972010-06-29T21:50:24.377+02:002010-06-29T21:50:24.377+02:00This is great work! If I want to use this in a pr...This is great work! If I want to use this in a program I'm writing how should I credit this?jonnyflashhttps://www.blogger.com/profile/06417844872416400954noreply@blogger.comtag:blogger.com,1999:blog-3704048544762396176.post-11941247443987380392010-05-14T16:49:55.429+02:002010-05-14T16:49:55.429+02:00sorry, no, it would go the opposite directionsorry, no, it would go the opposite directionPavelnoreply@blogger.comtag:blogger.com,1999:blog-3704048544762396176.post-24861977370695373072010-05-14T16:38:51.851+02:002010-05-14T16:38:51.851+02:00"I'm glad you liked it. I peeked into one..."I'm glad you liked it. I peeked into one of our spectrometers and I would say 600 nm is orange. Pretty close to the header orange bar on this blog's title. A bit different than what MS Paint gives for [255, 176, 0]. Afterall, this algorithm is just an approximation :-) It may also be just my screen... "<br /><br />I'm not sure, but maybe you should correct it for gamma. Then it woudl be 255,112,0, If I counted it correctly.Pavelnoreply@blogger.comtag:blogger.com,1999:blog-3704048544762396176.post-29004121107850017122010-05-08T15:49:53.828+02:002010-05-08T15:49:53.828+02:00Aaron, yes, that's the right way of measuring ...Aaron, yes, that's the right way of measuring spectra. It may be interesting to use e.g. solar spectrum detected this way to measure spectral sensitivity of different sensors (point-and-shoot, mobile phone camera, webcam, ...). I guess these chips may differ a lot in the filters they use to selectively measure R, G and B channels. The drawback of using such sensors may be just 8-bit color/intensity(?). The pro stuff I'm using at work generally has 16-bit A/D converters (and of course is grayscale only).R.L.https://www.blogger.com/profile/14598815714075739940noreply@blogger.comtag:blogger.com,1999:blog-3704048544762396176.post-12156800910553176052010-05-08T12:52:56.904+02:002010-05-08T12:52:56.904+02:00Actually I was working on this and discovered that...Actually I was working on this and discovered that first and foremost - the biggest issue is to translate the picture into gray scale, which is purely the intensity of the light at that pixel position (Gray Scale = Intensity, 0-256).<br /><br />If one then ran a simple program condensing the picture via the average/mean to a single pixel high picture, with the full width, then plotting position against intensity would give a very good outcome (and is probably fairly easily attained). If one wanted to finetune that, then you'd need something, either a xenon/neon bulb (which run off fuck all power), which have very well known and documented spectra. Using trigonometry one could work back from the 'absolute' wavelength in nm of the known peaks/troughs of the neon/xenon bulb, then use that to assign absolute wavelengths to the remaining pixels along the bottom of the picture.<br /><br />One very useful part of this, is that every one pixel high row is effectively a separate spectrograph, so in averaging several hundred of them to reduce it to a single pixel, you would reduce noise dramaticallyAaron Troy Smallhttps://www.blogger.com/profile/17400242374316268955noreply@blogger.comtag:blogger.com,1999:blog-3704048544762396176.post-21737235926645918232010-05-08T09:13:25.916+02:002010-05-08T09:13:25.916+02:00Joseph, OK, I get it. First, there is no grating a...Joseph, OK, I get it. First, there is no grating and no slit in an iPhone. If you are interested in these terms, try wikipedia pages on <i>diffraction grating</i> and <i>monochromator</i>.<br />Second, if I understand this correctly, you cannot use an LCD like the one in iPhone to produce monochromatic light. You can produce some color, which would look the same to the human eye by carefully mixing the R, G and B components. In your case, if you only need the approximation, start with this algorithm to produce some color estimate, then use sodium lamp (we have street lamps here which are of this kind) and compare the color to the one displayed on your iPhone. You will probably need to manually tweak the RGB values to get as close as possible. Then hope that all iPhones have the same display.<br />If you really need monochromatic light, you will have to use some diffraction element (either a grating or a prism), set it up properly and filter some light source with it. It's not as difficult as it may sound.R.L.https://www.blogger.com/profile/14598815714075739940noreply@blogger.comtag:blogger.com,1999:blog-3704048544762396176.post-31166050931143046562010-05-07T23:52:33.948+02:002010-05-07T23:52:33.948+02:00Thanks R.L. More specifically, I am interested in ...Thanks R.L. More specifically, I am interested in producing a 589 nm on the iPhone. The first question, what would be the line spread using the RGB conversion. The second question involves "GRATING DISPERSION VALUE and a WIDTH OF THE OF THE OUTPUT SLIT" In regard to the iPhone, I am not familiar with these terms. Where can I learn more about them.Josephnoreply@blogger.comtag:blogger.com,1999:blog-3704048544762396176.post-85541562549714260352010-05-07T20:47:24.271+02:002010-05-07T20:47:24.271+02:00Joseph, can you elaborate on that a little bit mor...Joseph, can you elaborate on that a little bit more? Using RGB -> nm conversion is generally not a good idea. I never heard of people trying to use it in a research environment. If you are interested in the 'cleanliness' of monochromator output, just get grating dispersion value and a width of the output slit.R.L.https://www.blogger.com/profile/14598815714075739940noreply@blogger.comtag:blogger.com,1999:blog-3704048544762396176.post-30079358197636652732010-05-07T20:06:45.925+02:002010-05-07T20:06:45.925+02:00Has anyone matched the RGB conversion to nm agains...Has anyone matched the RGB conversion to nm against a spectrophotometer to determine the wavelength spread in defining a monochromatic wavelength?Josephnoreply@blogger.comtag:blogger.com,1999:blog-3704048544762396176.post-58475902464977585812010-02-17T20:06:12.513+01:002010-02-17T20:06:12.513+01:00Hello Aaron,
In theory, you can try this. At least...Hello Aaron,<br />In theory, you can try this. At least between 420 and 645 nm the conversion should be straightforward. I would start by picking the most intense colour (R, G or B), normalizing it to 255 and reverse-engineering the wavelength from there. You want your spectra very clear, noise-free, preferably not distorted by camera spectral selectivity and with no mixed colours. <br />However, I would recommend taking some reference line spectra (mercury lamp, sodium, xenone, maybe ceiling fluorescent tube will work too), identifying known lines and computing wavelength axis from that. This will give you much more reliable data. After that, use your original RGB data to extract intensity information (black & white sensor would be probably better for this).<br />R.L.R.L.https://www.blogger.com/profile/14598815714075739940noreply@blogger.comtag:blogger.com,1999:blog-3704048544762396176.post-86446967035885723422010-02-16T23:13:19.805+01:002010-02-16T23:13:19.805+01:00I am interested in changing a spectrum in RGB into...I am interested in changing a spectrum in RGB into wavelengths (for graphing purposes). Any ideas?Aaron Troy Smallhttps://www.blogger.com/profile/17400242374316268955noreply@blogger.comtag:blogger.com,1999:blog-3704048544762396176.post-3963795453562119332009-11-20T13:45:20.020+01:002009-11-20T13:45:20.020+01:00Dear B26354,
the code from efg2.com uses a gamma ...Dear B26354,<br /><br />the code from efg2.com uses a gamma correction which I have omitted. So the answer is ... use whatever you like :-)<br /><br />RLR.L.https://www.blogger.com/profile/14598815714075739940noreply@blogger.comtag:blogger.com,1999:blog-3704048544762396176.post-18728811422545873632009-11-19T21:50:47.904+01:002009-11-19T21:50:47.904+01:00I used the converter at http://utilitymill.com/uti...I used the converter at http://utilitymill.com/utility/Convert_WaveLength_to_RGB_Value and at http://www.efg2.com/Lab/ScienceAndEngineering/Spectra.htm and I get different values.<br />For example 525nm gets me 54,255,0 and 74,255,0 respectively.<br /><br />How do I know which one is right?Unknownhttps://www.blogger.com/profile/08049818290874004321noreply@blogger.comtag:blogger.com,1999:blog-3704048544762396176.post-2653023170658258982009-11-12T13:15:07.587+01:002009-11-12T13:15:07.587+01:00Hello James,
Thank you for your comment. I don'...Hello James,<br />Thank you for your comment. I don't know of a code extension but it could be easy to do it yourself. I believe you could just make an average of RGB values at the wavelengths you have intensities for, weighted by the intensities. I have been moving to another country and didn't have much time recently. I should have more time in the coming weeks and can help you out with this if you are still interested.<br />RLR.L.https://www.blogger.com/profile/14598815714075739940noreply@blogger.comtag:blogger.com,1999:blog-3704048544762396176.post-43749781928905033622009-10-30T14:53:14.586+01:002009-10-30T14:53:14.586+01:00Hello,
I am interested in inputing a set of inten...Hello,<br /><br />I am interested in inputing a set of intensities accorss the visual spectrum and receiving an output of the RGB colour you would actually see. Do you know of an extension to this code which does such a thing?<br /><br />Many Thanks,<br /><br />James Sheils<br />Physics Teacher<br />Manchester Grammar Schooljamesthenabignumberhttps://www.blogger.com/profile/06201545058273960749noreply@blogger.comtag:blogger.com,1999:blog-3704048544762396176.post-76099928327841863162009-06-17T15:02:31.760+02:002009-06-17T15:02:31.760+02:00Paolo - thanks for the link. I'll definitely t...Paolo - thanks for the link. I'll definitely take a look at this once I got some time on my hands.<br /><br />Gregory - I'm glad you liked it. I peeked into one of our spectrometers and I would say 600 nm is orange. Pretty close to the header orange bar on this blog's title. A bit different than what MS Paint gives for [255, 176, 0]. Afterall, this algorithm is just an approximation :-) It may also be just my screen...R.L.https://www.blogger.com/profile/14598815714075739940noreply@blogger.comtag:blogger.com,1999:blog-3704048544762396176.post-24239195225721169782009-06-16T16:34:55.644+02:002009-06-16T16:34:55.644+02:00This is cool. I made it into an online wavelength...This is cool. I made it into an <a href="http://utilitymill.com/utility/Convert_WaveLength_to_RGB_Value" rel="nofollow">online wavelength to RGB converter here</a>.<br /><br />I put in 600 nm as the default value. What color should that be?Unknownhttps://www.blogger.com/profile/08621044314054420926noreply@blogger.comtag:blogger.com,1999:blog-3704048544762396176.post-1754062924032989782009-05-29T15:33:36.394+02:002009-05-29T15:33:36.394+02:00http://r-forge.r-project.org/R/?group_id=160
At th...http://r-forge.r-project.org/R/?group_id=160<br />At the link above you can find a collection of R packages that could be of some help for your task, take a look particularly at the spectr* packages.<br />Hope it helps!Paolohttps://www.blogger.com/profile/01969817827028660433noreply@blogger.com