Apakah ada yang tahu rumus untuk mengubah frekuensi cahaya menjadi nilai RGB?
algorithm
language-agnostic
rgb
formula
approximation
Shaul Behr
sumber
sumber
Jawaban:
Berikut penjelasan rinci dari keseluruhan proses konversi: http://www.fourmilab.ch/documents/specrend/ . Kode sumber disertakan!
sumber
Untuk orang-orang yang malas (seperti saya), berikut adalah implementasi di java dari kode yang ditemukan di jawaban @ user151323 (yaitu, hanya terjemahan sederhana dari kode pascal yang ditemukan di Spectra Lab Report ):
sumber
Wavelength<=439
keWavelength<440
.Ide umum:
Langkah 1 dan 2 mungkin berbeda.
Ada beberapa fungsi pencocokan warna, tersedia sebagai tabel atau sebagai perkiraan analitik (disarankan oleh @Tarc dan @Haochen Xie). Tabel adalah pilihan terbaik jika Anda membutuhkan hasil presisi yang halus.
Tidak ada satu pun ruang warna RGB. Beberapa matriks transformasi dan berbagai jenis koreksi gamma dapat digunakan.
Di bawah ini adalah kode C # yang saya dapatkan baru-baru ini. Ini menggunakan interpolasi linier di atas tabel "pengamat standar CIE 1964" dan matriks sRGB + koreksi gamma .
Hasil untuk kisaran 400-700 nm:
sumber
Meskipun ini adalah pertanyaan lama dan sudah mendapatkan beberapa jawaban bagus, ketika saya mencoba menerapkan fungsi konversi seperti itu di aplikasi saya, saya tidak puas dengan algoritme yang sudah tercantum di sini dan melakukan penelitian sendiri, yang memberi saya hasil yang baik. Jadi saya akan memposting jawaban baru.
Setelah beberapa penelitian, saya menemukan makalah ini, Pendekatan Analitik Sederhana untuk Fungsi Pencocokan Warna CIE XYZ , dan mencoba mengadopsi algoritma fit Gaussian multi-lobus yang diperkenalkan dalam aplikasi saya. Makalah ini hanya menjelaskan fungsi untuk mengubah panjang gelombang ke nilai XYZ yang sesuai , jadi saya menerapkan fungsi untuk mengubah XYZ ke RGB dalam ruang warna sRGB dan menggabungkannya. Hasilnya luar biasa dan layak dibagikan:
kode saya ditulis di Java 8, tetapi seharusnya tidak sulit untuk mem-port-nya ke versi Java yang lebih rendah dan bahasa lain.
sumber
transfer
DoubleUnaryOperator (jadi penjelasan di komentar saya sebelumnya tidak benar), jadi silakan periksa kode baru.1.
hanya 1 tetapi jenis akandouble
bukannyaint
Anda sedang berbicara tentang mengubah dari panjang gelombang ke nilai RGB.
Lihat di sini, mungkin akan menjawab pertanyaan Anda. Anda memiliki utilitas untuk melakukan ini dengan kode sumber serta beberapa penjelasan.
WaveLengthToRGB
sumber
Saya rasa saya sebaiknya menindaklanjuti komentar saya dengan jawaban formal. Pilihan terbaik adalah menggunakan ruang warna HSV - meskipun rona mewakili panjang gelombang, ini bukan perbandingan satu-ke-satu.
sumber
Saya melakukan kesesuaian linier dari nilai rona dan frekuensi yang diketahui (menghilangkan warna merah dan ungu karena mereka meluas sejauh ini dalam nilai frekuensi sehingga mereka sedikit condong) dan saya mendapatkan persamaan konversi kasar.
Ini berjalan seperti
frekuensi (dalam THz) = 474 + (3/4) (Hue Angle (dalam derajat))
Saya telah mencoba melihat-lihat dan melihat apakah ada yang menemukan persamaan ini, tetapi saya belum menemukan apa pun hingga Mei 2010.
sumber
Metode 1
Ini sedikit dibersihkan dan diuji versi C ++ 11 dari @ haochen-xie. Saya juga menambahkan fungsi yang mengubah nilai 0 ke 1 menjadi panjang gelombang dalam spektrum terlihat yang dapat digunakan dengan metode ini. Anda bisa meletakkan di bawah ini dalam satu file header dan menggunakannya tanpa ketergantungan apa pun. Versi ini akan dipertahankan di sini .
Plot warna dari 375nm hingga 725nm terlihat seperti di bawah ini:
Satu masalah dengan metode ini adalah kenyataan bahwa ia hanya bekerja antara 400-700nm dan di luar itu ia secara tajam jatuh ke hitam. Masalah lainnya adalah biru yang lebih sempit.
Sebagai perbandingan, di bawah ini adalah warna dari Vision FAQ di maxmax.com:
Saya menggunakan ini untuk memvisualisasikan peta kedalaman di mana setiap piksel mewakili nilai kedalaman dalam meter dan ini terlihat seperti di bawah ini:
Metode 2
Ini diimplementasikan sebagai bagian dari pustaka file tunggal header-only bitmap_image oleh Aeash Partow:
Plot panjang gelombang dari 375-725nm terlihat seperti di bawah ini:
Jadi ini lebih bisa digunakan dalam 400-725nm. Ketika saya memvisualisasikan peta kedalaman yang sama seperti pada metode 1, saya mendapatkan di bawah. Ada masalah yang jelas dari garis hitam yang menurut saya menunjukkan bug minor dalam kode ini yang belum saya lihat lebih dalam. Juga violet sedikit lebih sempit dalam metode ini yang menyebabkan kontras yang lebih sedikit untuk objek yang jauh.
sumber
Proyeksikan CIExy panjang gelombang ke arah putih D65 ke gamut sRGB
sumber