레이블이 optics인 게시물을 표시합니다. 모든 게시물 표시
레이블이 optics인 게시물을 표시합니다. 모든 게시물 표시

2026년 7월 28일 화요일

투과형 collimator는 색수차가 발생합니다.

 collimator의 내부설계에 따라 파장에 따른 굴절률 차이로 인해 필연적으로 색수차가 발생합니다.

그래서, 평행광은 특정 파장대의 빛만 적용되며, 그 외의 파장대의 빛들은 이상적인 평행광이 될 수 없습니다.

즉, 모든 파장을 동시에 완벽한 평행광을 만들 수 없습니다.

해결책1 : 색지움 collimator (Archromatic Doublet) - 색수차 억제

굴절율 변화율이 서로 다른 두 개 이상의 유리를 조합하여 설계합니다. 일반적으로 가시광선 영역의 두 가지 파장(주로 적색과 청색)의 초점 거리를 강제로 일치시켜, 가시광선 전반에서 색수차를 크게 줄여줍니다. 완전히 제거되지는 않지만, 일반적인 목적에서는 충분히 평행한 광선(Collimated beam)을 얻을 수 있습니다.

해결책2 : 반사형 collimator (거울) 

색수차를 원천적으로 차단해야 하는 정밀 광학계나 광대역(자외선~적외선 동시 사용) 매질에서는 렌즈 대신 오목 거울(예: 축외 포물면 거울, Off-Axis Parabolic Mirror)을 콜리메이터로 사용합니다.

렌즈의 구성요소의 용어 정리

 




2018년 4월 11일 수요일

How to use USB4000 Spectrometer in Linux system (Debian)

There are two kinds of tools that cooperate USB4000 under GNU Debian distribution.
The first one is that C/C++ interface comes from OceanOptics Official, and the other is that the Python package was made as Open Source contribution.


1. Preliminary


The first thing to do before tools installation is to configure the system allowing any one to access the USB4000 without root premission.


1.1. Download SeaBreeze (i.e. OceanOptics Official tool for linux system).

https://sourceforge.net/projects/seabreeze/?source=typ_redirect





1.2. Extract *.zip file and copy the rules file into system.


With root permission,


# cp seabreeze-3.0.11/SeaBreeze/os-support/linux/10-oceanoptics.rules /etc/dev/rules.d/


1.3.  Plugin USB4000 and verify the connection.
 

You can see the USB4000 with Vendor ID: 0x2457 and Product ID: 0x1022.


2. OceanOptics' Offical Tool (i.e. SeaBreeze)


The tool contains C/C++ api, utilities and test codes.



2.1. Register the library path.


Before the compilation, load library path has to be registered.


# cd ~/seabreeze-3.0.11/SeaBreeze

#  export LD_LIBRARY_PATH="$PWD/lib"


2.2. Compilation with some errors and modification.


Once compiling the SeaBreeze, many errors are poped out that is actually kinds of warnings for c++11 deprecation.


This kinds of erros could be removed by comment out '-Werror' option.




2.3. Install dependencies.


# apt install libusb-dev, ....


2.4. Complete compilation.


# make


2.5. Execution of test code.

# ./test/seabreeze_test_posix




3. Open Sourced Toolkit (linux drivers for usb spectrometers)

This tool is open source tool that supports several usb spectrometers (i.e. avantes, hamamatsu, and OceanOptics). That is basically written by Python script, and internally using Kernel interface or Libusb. In otherwords, it do not requires any kinds of additional kernel driver.

3.1. Download python package.


Click Download Snapshot.

3.2. Install dependencies.

# pip install numpy, matlibplot, pyusb

3.3. Modification for visualizing live graph.

#!/usr/bin/env python3 -w

# python module to communicate with an Ocena Optics USB spectrometer
#
# Copyright (C) Wolfgang Schoenfeld (wolfgang.schoenfeld@hzg.de) and
#               Carsten Frank       (carsten.frank@hzg.de)
#
#       This program is free software; you can redistribute it and/or
#       modify it under the terms of the GNU General Public License as
#       published by the Free Software Foundation, version 2.
#
# This module is suitable to control a Avantes USB spectrometer. The following
# types are supported:
# - USB 4000
# - probably USB 2000

# C H A N G E S #
# 28. 07. 2012 Carsten Frank
# - created based on the Hamamatsu code
# - also based on the documentation given in the USB4000-OEM_Data-Sheet.pdf
#   which is publicly available (http://www.oceanoem.com/).

from __future__ import print_function

import os
import os.path
import re
import time
import sys
import numpy as np
import multiprocessing
import ctypes
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib import style
#import cv2

#sys.path.append('/home/carsten/Programme/python/FiaSia')
#sys.path.append('/home/carsten/Programme/python')
#from findUSBserialDevice import getDeviceFileFromAddress, testAddress

import usb.core, usb.util

USB_USBSPEC_VENDOR_ID = 0x2457
USB_USBSPEC_PRODUCT_ID_USB4000 = 0x1022
USB_USBSPEC_PRODUCT_ID_USB650 = 0x1014   # not working, kept for future use
PIXEL_COUNT_USB4000 = 3840

class USB4000: ## GUI OoUSB4000 ## Adds this device to the spectrometers listed in the GUI
    '''Connect to a Ocean Optics mini spectrometer via USB. '''

    # device name should be either the USB-address or the serial numer
    def __init__(self, deviceName = None):
        # the device name would be the 'device' in the "/dev/" folder (linux)
        self.deviceName   = None
        self.serialNumber = None

        # Only needed for pyUSB. Checks if the configuration was already set.
        self.configurationSet = False

        # self.usedInterface is set in findAllConnectedSpectrometers
        # self.usedInterface equals None if no device is found
        devNotFound = True

        # If no spectrometer is foud this function complains and exits!
        self.specs = self._findAllConnectedSpectrometers()

        if self.usedInterface == 'pyusb':
                if  deviceName == None:
                        # use the 'first' spectrometer
                        self.serialNumber = self.specs.keys()[0]
                        self.deviceName   = None
                        self.basePath     = None
                        devNotFound = False
                else:
                        # only the serial number would be delivered as device name in this context (pyusb)
                        if self.specs.has_key(deviceName):
                                self.serialNumber = key
                                self.deviceName   = None
                                self.basePath     = None
                                devNotFound       = False

        elif self.usedInterface == 'kernel':
                if  deviceName == None:
                        # use random device (if more than one device is attached)
                        self.serialNumber = self.specs.keys()[0]
                        self.deviceName = self.specs[self.serialNumber][0]
                        self.basePath = os.path.join("/sys/bus/usb/drivers/usbhspec/", self.specs[self.serialNumber][1])
                        devNotFound = False
                else:
                        # if it is an valid usb address like '8-2:1.0'
                        if testAddress(deviceName):
                                for key, value in self.specs.iteritems():
                                        if value[1] == deviceName:
                                                self.deviceName = value[0]
                                                self.basePath = os.path.join("/sys/bus/usb/drivers/usbhspec/", value[1])
                                                devNotFound = False
                                                break
                        else:
                                for key, value in self.specs.iteritems():
                                        if value[0] == deviceName:
                                                self.deviceName = value[0]
                                                self.basePath = os.path.join("/sys/bus/usb/drivers/usbhspec/", value[1])
                                                devNotFound = False
                                                break
                                        if key == deviceName:
                                                self.deviceName = value[0]
                                                self.basePath = os.path.join("/sys/bus/usb/drivers/usbhspec/", value[1])
                                                devNotFound = False
                                                break

        if devNotFound == True:
                print('Device %s not found! Exiting ...'%(deviceName))
                sys.exit()

        if self.usedInterface == 'kernel':
                #: First calibration coefficient of the spectrometer. Pixel counting starts at 1!
                self.startWavelength = float(file(os.path.join(self.basePath,"a0")).read())
                #: Second calibration coefficient.
                self.firstKoeff      = float(file(os.path.join(self.basePath,"a1")).read())
                #: Third calibration coefficient.
                self.secondKoeff     = float(file(os.path.join(self.basePath,"a2")).read())
                #: Fourth calibration coefficient.
                self.thirdKoeff      = float(file(os.path.join(self.basePath,"a3")).read())
                #: Fifth calibration coefficient.
                self.fourthKoeff     = float(file(os.path.join(self.basePath,"a4")).read())
                #: Guess what!
                self.fifthKoeff      = float(file(os.path.join(self.basePath,"a5")).read())
                self.deviceName = file(os.path.join(self.basePath,"device_name")).read().strip()
                self.sensorName = file(os.path.join(self.basePath,"sensor_name")).read().strip()

                self.devicePath = "/dev/%s" % (self.deviceName)
        else: # self.usedInterface == 'pyusb'
                # we do know the serialNumber!

                value = self.specs[self.serialNumber]
                dev = value[3]

                # create endpoints

                cfg = dev.get_active_configuration()
                interface_number = cfg[(0,0)].bInterfaceNumber
                alternate_setting = usb.control.get_interface(dev, interface_number)
                intf = usb.util.find_descriptor(cfg, bInterfaceNumber = interface_number,bAlternateSetting = alternate_setting)

                self.ep1Out = usb.util.find_descriptor(intf, custom_match = lambda e: e.bEndpointAddress == 0x01)
                self.ep1In  = usb.util.find_descriptor(intf, custom_match = lambda e: e.bEndpointAddress == 0x81)
                self.ep2    = usb.util.find_descriptor(intf, custom_match = lambda e: e.bEndpointAddress == 0x82)
                self.ep6    = usb.util.find_descriptor(intf, custom_match = lambda e: e.bEndpointAddress == 0x86)

                #: Get start wavelength
                self.startWavelength = self._query(0x01, "num")
                #: Second calibration coefficient.
                self.firstKoeff      = self._query(0x02, "num")
                #: Third calibration coefficient.
                self.secondKoeff     = self._query(0x03, "num")
                #: Fourth calibration coefficient.
                self.thirdKoeff      = self._query(0x04, "num")
                #: Fifth calibration coefficient.
                self.fourthKoeff     = 0.0
                #: Guess what!
                self.fifthKoeff      = 0.0
                self.sensorName = ''

                self.deviceName = dev


        # Default
        self.pixelOffset = 0
        # S10420-1006/-1106 CCD image sensor see documentation (Device structure)
        if (self.sensorName == "S10420-1106") or (self.sensorName == "S10420-1006"):
                self.pixelOffset = 10
                print("Sensor '%s' means pixel offset of %d" % (self.sensorName, self.pixelOffset))
        elif (self.sensorName.find("S8377") > -1) or (self.sensorName.find("S8378") > -1):
                self.pixelOffset = 0
                print("Sensor '%s' means pixel offset of %d" % (self.sensorName, self.pixelOffset))



        # gereate wavelength array
        self.wlArr = np.zeros(PIXEL_COUNT_USB4000)
        for pix in range(PIXEL_COUNT_USB4000):
                self.wlArr[pix] = self.startWavelength       + \
                                   pix *   self.firstKoeff   + \
                                  (pix**2)*self.secondKoeff  + \
                                  (pix**3)*self.thirdKoeff   + \
                                  (pix**4)*self.fourthKoeff  + \
                                  (pix**5)*self.fifthKoeff
        print(self.wlArr)

    def findAllConnectedSpectrometers(self):
            return self.specs
    def _findAllConnectedSpectrometers(self):
        """Function to find all connected USB-spectrometers

        Returns a list/dictionary? with spectrometers containing:
        - device name
        - serial number
        - start wavelength
        """

        specs = {}
        self.usedInterface = "kernel"

        basePath = "/sys/bus/usb/drivers/usbhspec/"
        if not os.path.exists(basePath):
                self.usedInterface = "pyusb"
                print("No spectrometer found using the kernel module.")
                print("Now testing pyusb!")

        if self.usedInterface == "kernel":
                fList = os.listdir(basePath)

                for i in fList:
                        mtch = re.search("\d\-\d.*\:\d+\.\d+", i)
                        if mtch:
                                serNr = open(os.path.join(basePath, i, "serial_number"), "r").read().strip()
                                res = getDeviceFileFromAddress("usb", i)
                                if len(res) <> 1:
                                        print("Something went wrong. I found two USB devices with the same path!")
                                        for i in res:
                                                print(i)
                                        print("PLEASE call someone (Carsten) who knows what to do now!")
                                        sys.exit()

                                specs[serNr] = (res[0][0], i, "%.0f" % (float(file(os.path.join(basePath, i,"a0")).read())))
        elif self.usedInterface == "pyusb":
                # use the pyusb interface (only ONE of these interfaces WILL work)
                devs = list(usb.core.find(idVendor=USB_USBSPEC_VENDOR_ID, idProduct=USB_USBSPEC_PRODUCT_ID_USB4000, find_all=True))
                #devs = usb.core.find(idVendor=USB_USBSPEC_VENDOR_ID, idProduct=USB_USBSPEC_PRODUCT_ID_USB650, find_all=True)
                if len(devs) > 0:
                        print("Found %d spectrometer(s) via pyusb!" % (len(devs)))
                else:
                        print("Also no spectrometer found using pyusb.")

                # find alls connected devices
                for dev in devs:
                        #dev.set_configuration()
                        #cfg = dev.get_active_configuration()
                        #interface_number = cfg[(0,0)].bInterfaceNumber
                        #alternate_setting = usb.control.get_interface(dev, interface_number)
                        #intf = usb.util.find_descriptor(cfg, bInterfaceNumber = interface_number,bAlternateSetting = alternate_setting)

                        cfg=dev[0]
                        intf=cfg[(0, 0)]

                        self.ep1Out=intf[0]
                        self.ep1In =intf[3]

                        #self.ep1Out = usb.util.find_descriptor(intf, custom_match = lambda e: e.bEndpointAddress == 0x01)
                        #self.ep1In  = usb.util.find_descriptor(intf, custom_match = lambda e: e.bEndpointAddress == 0x81)

                        readSuccess = False
                        while not readSuccess:
                                # INITIALIZE
                                self.ep1Out.write(chr(0x01))
                                time.sleep(0.5)
                                readSuccess = True
                                # get integration time

                                #self.ep1Out.write(chr(0xfe))
                                #try:
                                        #res = self.ep1In.read(64)
                                        #readSuccess = True
                                #except usb.core.USBError:
                                        #print "Failed"
                                        #pass

                        #int_time = (res[5]<<24 br="" res="">                        #print int_time

                        # get necessary data for all devices {'510C2114': ('usbhspec0', '5-2:1.0', '324'  )}
                        #                                    { serialNo : ( 'pyusb'   ,  None    , firstWL)}
                        # get serial number
                        serNr = self._query(0x00, "str")
                        # get a0
                        a0 = self._query(0x01, "num")
                        del(self.ep1Out, self.ep1In)
                        specs[serNr] = ( 'pyusb'   ,  None    ,  "%.0f" % (float(a0)), dev)
        else:
                print("This point should never be reached!")
                sys.exit()

        if len(specs) == 0:
                self.usedInterface = None

        return specs

    def _query(self, byte, decode=None):
        self.ep1Out.write(chr(0x05) + chr(byte))
        res = self.ep1In.read(64)
        if   decode == 'str':
            s   = ''.join(map(chr,res[2:])).rstrip()
            res = s.replace('\x00','')
            res = res.replace('\xa4','')
        elif decode == 'num':
            s   = ''.join(map(chr,res[2:])).rstrip()
            res = s.replace('\x00','')
            res = res.replace('\xa4','')  #FIXME: ??
            res = float(res)
        return res

    def setIntegrationTime(self, intTime, test=True):
        # integration_time possible values between 10 - 65535000 (in usec)
        if (intTime < 10) or  (intTime > 65535000):
                print("USB4000.setIntegrationTime : Integration Time not allowed! please use vaues between")
                print("10 and 65535000 us")
                return False
        while True:
                if   self.usedInterface == 'pyusb':
                        c = []
                        c.append( intTime        & 0xFF )
                        c.append((intTime >>  8) & 0xFF )
                        c.append((intTime >> 16) & 0xFF )
                        c.append((intTime >> 24) & 0xFF )
                        self.ep1Out.write(chr(0x02) + bytearray(c))
                else:
                        print("Interface not yet implemented")
                        sys.exit()

                if not test:
                        break
                time.sleep(.01)
                devIT = self.getIntegrationTime()
                print("setIntTime : %d  ----  deviceIntTime : %d" % (devIT, intTime))
                if devIT == intTime:
                        break
                if (time.time() - startT) > 1.0:
                        return False
        self.integrationTime = intTime
        return True

    def getIntegrationTime(self):
        # integration_time possible values between 10000 and 10000000 (in usec)
        if   self.usedInterface == 'pyusb':

                startT = time.time()
                self.ep1Out.write(chr(0xfe))
                res    = self.ep1In.read(64)
                #while len(res) <> 4:
                        #print("--------------------------------- getIntegrationTime -- Answer incorrect (too long or too short)!")
                        #time.sleep(.01)
                        #res    = self.deviceName.ctrl_transfer(bmRequestType = 0xc0, bRequest = 0x0b, wValue = 0x01, wIndex = 0x00, data_or_wLength = 4, timeout = 2000)
                        #if (time.time() - startT) > .5:
                                #raise
                intTime = (res[5] << 24) + (res[4] << 16) + (res[3] << 8) + res[2]
        elif self.usedInterface == 'kernel':
                print("Interface not yet implemented")
                sys.exit()
        return intTime

    def getSensorName(self):
        return self.sensorName

    def getSerialNumber(self):
        return self.serialNumber

    def getSpectrum(self, timeout = None):
        """This function grabs spectral data from the spectrometer. Addidtional
        information is also encoded in the data read from the interface so
        take nothing for granted!

        I've got two different spectrometers from which I tried to conclude
        what to do with the data. I may have made invalid assumptions!

        You have to read 0x1040 bytes of data. These are 16bit numbers so it does
        make sense to calculate these numbers from the data and the only use those
        integers.

        The first number (16 bit in this context) was alwas 2. That only changes
        if you read data if the spectrometer is not yet ready (integration time).
        If the spectrometer isn't ready all numers are zero.

        The second number is an index which is 0,1 or 2 and just counts up.

        Third is the amount of active pixels (in contrast to the amount of pixels
        sixth number (index 5)). Please see the documentation to your image sensor
        (e.g. S10420-1106 from Hamamtsu).

        Forth (index 3) is the most important number because it says where to find
        the first pixel in the whole dataset of 0x1040/2 = 0x820 16bit numbers.

        The fifth seems to be the end index because startIndex + amountOfPixels = endIndex
        HOWEVER in my case the end index is higer than 0x820 which means that I can be
        very wrong with my interpretation.

        In my case and using the S10420-1106 sensor I found that the first four numbers
        of the spectrum (starting with startIndex) seem to be darkened pixels. You can
        increase the integration time as much as you wish these numbers stay (more or less)
        the same. Use at your own risc!

        Actually the spectrum seems to start at startIndex + 10 pixels/numbers which was
        veryfied for MY spectrometer with a really good and freshly checked laboratory
        spectrometer from Perkin Elmer (wavelength correctness was checkt with the aid of
        special filters).
        So I calculate the start of the spectrum unsing
        startSpectrum = startIndex + (amountOfPixels - amountOfActivePixels) / 2
        which seems to make sense.

        The wavelength correctness was VERY good compared to spectrometers from avantes,
        ocean optics and trios. We estimat an offset of about .4 nm over the whole spectrum
        which lies in the tolerance of of our measurement setup.
        """

        if timeout == None:
                timeout = self.integrationTime / 1000000.0 * 2.1
        startT = time.time()
        while 1:
                #: Grab data from the interface
                if self.usedInterface == 'pyusb':
                        # ask for the data
                        self.ep1Out.write(chr(0x09))
                        resArr = np.zeros(256 * 15)
                        resArrIndex = 0
                        # read four times from endpoint 6 an four times from ep2
                        while 1:
                                try:
                                        res = self.ep6.read(512)
                                except usb.core.USBError:
                                        if (time.time() - startT) > timeout:
                                                raise usb.core.USBError("Timeout")
                                        time.sleep(.01)
                                        continue
                                else:
                                        break

                        for i in range(0,len(res),2):
                                resArr[resArrIndex] = (res[i+1] << 8) + res[i]
                                resArrIndex += 1


                        for i in range(3):
                            res = self.ep6.read(512)
                            for i in range(0,len(res),2):
                                resArr[resArrIndex] = (res[i+1] << 8) + res[i]
                                resArrIndex += 1
                        for i in range(4,15):
                            res = self.ep2.read(512)
                            for i in range(0,len(res),2):
                                resArr[resArrIndex] = (res[i+1] << 8) + res[i]
                                resArrIndex += 1
                        sync_packet = self.ep2.read(1)
                        return resArr
                else:
                        return None

        return resArr

def frange(start, end=None, inc=None):
    "A range function, that does accept float increments..."

    if end == None:
        end = start + 0.0
        start = 0.0

    if inc == None:
        inc = 1.0

    L = []
    while 1:
        next = start + len(L) * inc
        if inc > 0 and next >= end:
            break
        elif inc < 0 and next <= end:
            break
        L.append(next)

    return L

pauseEvent = False
animationHandle = None

def main(argv):
    global animationHandle
    
    ham = USB4000()
    #print ham.findAllConnectedSpectrometers()
    ham.setIntegrationTime(100000)
    res = ham.getSpectrum()
    print(res, len(res), max(res))
    
    fig = plt.figure()
    fig.suptitle('Demo. of Spectrometer')

    ax = fig.add_subplot(1, 1, 1)
    #plt.axis([0, len(res), 0, 40000])
    
    '''
    li, = ax.plot(ham.wlArr, res, c='r')
    #ax.relim()
    #ax.autoscale_view(True, True, True)
    #fig.canvas.draw()
    plt.show(block=False)

    while True:
        try:
            res = ham.getSpectrum()
            li.set_ydata(res)
            fig.canvas.draw()
        except KeyboardInterrupt:
            break

    '''
    def draw_spectrum(i):
        res = ham.getSpectrum()
        ax.clear()
        ax.set_title('USB4000')
        #ax.set_xlim(ham.wlArr.min(), ham.wlArr.max())
        #ax.set_ylim(0, 36000)
        ax.set_xlabel('Wavelength')
        ax.set_ylabel('Intensity')
        ax.plot(ham.wlArr, res, c='r')
        
    ax.relim()
    ax.autoscale_view(True, True, True)
    animationHandle = animation.FuncAnimation(fig, draw_spectrum, blit=False, interval=1, repeat=True)
    
    def on_click(event):
        global pauseEvent
        global animationaHandle
        #print('clicked')
        pauseEvent ^= True
        if pauseEvent:
            animationHandle.event_source.stop()
        else:
            animationHandle.event_source.start()

    fig.canvas.mpl_connect('button_press_event', on_click)

    plt.show()
    
    return 0
    
if __name__ == '__main__':
    sys.exit(main(sys.argv))


3.4. Execution.




4. References

https://sourceforge.net/projects/seabreeze/?source=typ_redirect

https://sourceforge.net/p/usbspecdrivers/wiki/Installation/



2016년 4월 20일 수요일

조명 장치의 조사 영역 분포도 검사 시뮬레이션

파이선 소스 코드


 #!/usr/bin/python  
 import Image  
 import numpy  
 import math  
 palette=((0, 0, 0), (0, 0, 10), (0, 0, 20), (0, 0, 30), (0, 0, 37), (0, 0, 42), (0, 0, 46), (0, 0, 50), (0, 0, 54), (0, 0, 58), (0, 0, 62), (0, 0, 66), (0, 0, 70), (0, 0, 74), (0, 0, 79), (0, 0, 82), (1, 0, 85), (1, 0, 87), (2, 0, 89), (2, 0, 92), (3, 0, 94), (4, 0, 97), (4, 0, 99), (5, 0, 101), (6, 0, 103), (7, 0, 105), (8, 0, 107), (9, 0, 110), (10, 0, 112), (11, 0, 115), (12, 0, 116), (13, 0, 117), (13, 0, 118), (14, 0, 119), (16, 0, 120), (18, 0, 121), (19, 0, 123), (21, 0, 124), (23, 0, 125), (25, 0, 126), (27, 0, 128), (28, 0, 129), (30, 0, 131), (32, 0, 132), (34, 0, 133), (36, 0, 134), (38, 0, 135), (40, 0, 137), (42, 0, 137), (44, 0, 138), (46, 0, 139), (48, 0, 140), (50, 0, 141), (52, 0, 142), (54, 0, 142), (56, 0, 143), (57, 0, 144), (59, 0, 145), (60, 0, 146), (62, 0, 147), (63, 0, 147), (65, 0, 148), (66, 0, 149), (68, 0, 149), (69, 0, 150), (71, 0, 150), (73, 0, 150), (74, 0, 150), (76, 0, 151), (78, 0, 151), (79, 0, 151), (81, 0, 151), (82, 0, 152), (84, 0, 152), (86, 0, 152), (88, 0, 153), (90, 0, 153), (92, 0, 153), (93, 0, 154), (95, 0, 154), (97, 0, 155), (99, 0, 155), (100, 0, 155), (102, 0, 155), (104, 0, 155), (106, 0, 155), (108, 0, 156), (109, 0, 156), (111, 0, 156), (112, 0, 156), (113, 0, 157), (115, 0, 157), (117, 0, 157), (119, 0, 157), (120, 0, 157), (122, 0, 157), (124, 0, 157), (126, 0, 157), (127, 0, 157), (129, 0, 157), (131, 0, 157), (132, 0, 157), (134, 0, 157), (135, 0, 157), (137, 0, 157), (138, 0, 157), (139, 0, 157), (141, 0, 157), (143, 0, 156), (145, 0, 156), (147, 0, 156), (149, 0, 156), (150, 0, 155), (152, 0, 155),  (153, 0, 155),  (155, 0, 155),  (156, 0, 155),  (157, 0, 155),  (159, 0, 155),  (160, 0, 155),  (162, 0, 155),  (163, 0, 155),  (164, 0, 155),  (166, 0, 154),  (167, 0, 154),  (168, 0, 154),  (169, 0, 153),  (170, 0, 153),  (171, 0, 153),  (173, 0, 153),  (174, 1, 152),  (175, 1, 152),  (176, 1, 152),  (176, 1, 152),  (177, 1, 151),  (178, 1, 151),  (179, 1, 150),  (180, 2, 150),  (181, 2, 149),  (182, 2, 149),  (183, 3, 149),  (184, 3, 149),  (185, 4, 149),  (186, 4, 149),  (186, 4, 148),  (187, 5, 147),  (188, 5, 147),  (189, 5, 147),  (190, 6, 146),  (191, 6, 146),  (191, 6, 146),  (192, 7, 145),  (192, 7, 145),  (193, 8, 144),  (193, 9, 144),  (194, 10, 143),  (195, 10, 142),  (195, 11, 142),  (196, 12, 141),  (197, 12, 140),  (198, 13, 139),  (198, 14, 138),  (199, 15, 137),  (200, 16, 136),  (201, 17, 135),  (202, 18, 134),  (202, 19, 133),  (203, 19, 133),  (203, 20, 132),  (204, 21, 130),  (205, 22, 129),  (206, 23, 128),  (206, 24, 126),  (207, 24, 124),  (207, 25, 123),  (208, 26, 121),  (209, 27, 120),  (209, 28, 118),  (210, 28, 117),  (210, 29, 116),  (211, 30, 114),  (211, 32, 113),  (212, 33, 111),  (212, 34, 110),  (213, 35, 107),  (213, 36, 105),  (214, 37, 103),  (215, 38, 101),  (216, 39, 100),  (216, 40, 98),  (217, 42, 96),  (218, 43, 94),  (218, 44, 92),  (219, 46, 90),  (219, 47, 87),  (220, 47, 84),  (221, 48, 81),  (221, 49, 78),  (222, 50, 74),  (222, 51, 71),  (223, 52, 68),  (223, 53, 65),  (223, 54, 61),  (224, 55, 58),  (224, 56, 55),  (224, 57, 51),  (225, 58, 48),  (226, 59, 45),  (226, 60, 42),  (227, 61, 38),  (227, 62, 35),  (228, 63, 32),  (228, 65, 29),  (228, 66, 28),  (229, 67, 27),  (229, 68, 25),  (229, 69, 24),  (230, 70, 22),  (231, 71, 21),  (231, 72, 20),  (231, 73, 19),  (232, 74, 18),  (232, 76, 16),  (232, 76, 15),  (233, 77, 14),  (233, 77, 13),  (234, 78, 12),  (234, 79, 12),  (235, 80, 11),  (235, 81, 10),  (235, 82, 10),  (235, 83, 9),  (236, 84, 9),  (236, 86, 8),  (236, 87, 8),  (236, 88, 8),  (237, 89, 7),  (237, 90, 7),  (237, 91, 6),  (238, 92, 6),  (238, 92, 5),  (238, 93, 5),  (238, 94, 5),  (239, 95, 4),  (239, 96, 4),  (239, 97, 4),  (239, 98, 4),  (240, 99, 3),  (240, 100, 3),  (240, 101, 3),  (241, 102, 3),  (241, 102, 3),  (241, 103, 3),  (241, 104, 3),  (241, 105, 2),  (241, 106, 2),  (241, 107, 2),  (241, 107, 2),  (242, 108, 1),  (242, 109, 1),  (242, 110, 1),  (243, 111, 1),  (243, 112, 1),  (243, 113, 1),  (243, 114, 1),  (244, 115, 0),  (244, 116, 0),  (244, 117, 0),  (244, 118, 0),  (244, 119, 0),  (244, 120, 0),  (244, 122, 0),  (245, 123, 0),  (245, 124, 0),  (245, 126, 0),  (245, 127, 0),  (246, 128, 0),  (246, 129, 0),  (246, 130, 0),  (247, 131, 0),  (247, 132, 0),  (247, 133, 0),  (247, 134, 0),  (248, 135, 0),  (248, 136, 0),  (248, 136, 0),  (248, 137, 0),  (248, 138, 0),  (248, 139, 0),  (248, 140, 0),  (249, 141, 0),  (249, 141, 0),  (249, 142, 0),  (249, 143, 0),  (249, 144, 0),  (249, 145, 0),  (249, 146, 0),  (249, 147, 0),  (250, 148, 0),  (250, 149, 0),  (250, 150, 0),  (251, 152, 0),  (251, 153, 0),  (251, 154, 0),  (251, 156, 0),  (252, 157, 0),  (252, 159, 0),  (252, 160, 0),  (252, 161, 0),  (253, 162, 0),  (253, 163, 0),  (253, 164, 0),  (253, 166, 0),  (253, 167, 0),  (253, 168, 0),  (253, 170, 0),  (253, 171, 0),  (253, 172, 0),  (253, 173, 0),  (253, 174, 0),  (254, 175, 0),  (254, 176, 0),  (254, 177, 0),  (254, 178, 0),  (254, 179, 0),  (254, 180, 0),  (254, 181, 0),  (254, 182, 0),  (254, 184, 0),  (254, 185, 0),  (254, 185, 0),  (254, 186, 0),  (254, 187, 0),  (254, 188, 0),  (254, 189, 0),  (254, 190, 0),  (254, 192, 0),  (254, 193, 0),  (254, 194, 0),  (254, 195, 0),  (254, 196, 0),  (254, 197, 0),  (254, 198, 0),  (254, 199, 0),  (254, 200, 0),  (254, 201, 1),  (254, 202, 1),  (254, 202, 1),  (254, 203, 1),  (254, 204, 2),  (254, 205, 2),  (254, 206, 3),  (254, 207, 4),  (254, 207, 4),  (254, 208, 5),  (254, 209, 6),  (254, 211, 8),  (254, 212, 9),  (254, 213, 10),  (254, 214, 10),  (254, 215, 11),  (254, 216, 12),  (254, 217, 13),  (255, 218, 14),  (255, 218, 14),  (255, 219, 16),  (255, 220, 18),  (255, 220, 20),  (255, 221, 22),  (255, 222, 25),  (255, 222, 27),  (255, 223, 30),  (255, 224, 32),  (255, 225, 34),  (255, 226, 36),  (255, 226, 38),  (255, 227, 40),  (255, 228, 43),  (255, 228, 46),  (255, 229, 49),  (255, 230, 53),  (255, 230, 56),  (255, 231, 60),  (255, 232, 63),  (255, 233, 67),  (255, 234, 70),  (255, 235, 73),  (255, 235, 77),  (255, 236, 80),  (255, 237, 84),  (255, 238, 87),  (255, 238, 91),  (255, 238, 95),  (255, 239, 99),  (255, 239, 103),  (255, 240, 106),  (255, 240, 110),  (255, 241, 114),  (255, 241, 119),  (255, 241, 123),  (255, 242, 128),  (255, 242, 133),  (255, 242, 138),  (255, 243, 142),  (255, 244, 146),  (255, 244, 150),  (255, 244, 154),  (255, 245, 158),  (255, 245, 162),  (255, 245, 166),  (255, 246, 170),  (255, 246, 175),  (255, 247, 179),  (255, 247, 182),  (255, 248, 186),  (255, 248, 189),  (255, 248, 193),  (255, 248, 196),  (255, 249, 199),  (255, 249, 202),  (255, 249, 205),  (255, 250, 209),  (255, 250, 212),  (255, 251, 216),  (255, 252, 219),  (255, 252, 223),  (255, 253, 226),  (255, 253, 229),  (255, 253, 232),  (255, 254, 235),  (255, 254, 238),  (255, 254, 241),  (255, 254, 244),  (255, 255, 246))    
 LEDs_on_head = 4  
 LED_interval = 60  
 shift_on_head = 30   
 head_angle = 30  
 distance_to_head = 200  
 #user_FOV_width  
 #user_FOV_height  
 #45 degree -> 0  
 #22.5 degree -> 400  
 #0 degree -> 2000  
 LED_FOV_dy = int(round(distance_to_head * math.tan(math.radians(45)) * 1.25))  
 LED_FOV_dx1 = int(round(distance_to_head * math.cos(math.radians(head_angle)) * math.tan(math.radians(45 + head_angle)) - distance_to_head * math.sin(math.radians(head_angle))))  
 LED_FOV_dx2 = int(round(distance_to_head * math.sin(math.radians(head_angle)) - distance_to_head * math.cos(math.radians(head_angle)) * math.tan(math.radians(head_angle - 45))))  
 LED_FOV_xcenter = LED_FOV_dx1  
 LED_FOV_ycenter = LED_FOV_dy  
 LED_FOV_width = LED_FOV_dx1 + LED_FOV_dx2  
 LED_FOV_height = 2 * LED_FOV_dy  
 print LED_FOV_width  
 print LED_FOV_height  
 def py_ang(v1, v2):  
   """ Returns the angle in radians between vectors 'v1' and 'v2'  """  
   cosang = numpy.dot(v1, v2)  
   sinang = numpy.linalg.norm(numpy.cross(v1, v2))  
   return numpy.arctan2(sinang, cosang)  
 LED_FOV_map = numpy.zeros((LED_FOV_height, LED_FOV_width))  
 v1 = numpy.array([-distance_to_head * math.sin(math.radians(head_angle)), 0, -distance_to_head * math.cos(math.radians(head_angle))])  
 for y in range(LED_FOV_height):  
   for x in range(LED_FOV_width):  
     dv = numpy.array([x - LED_FOV_xcenter, y - LED_FOV_ycenter, 0])  
     v2 = v1 + dv  
     ang = abs(math.degrees(py_ang(v1, v2)))  
     if ang > 45.0:  
       intensity = 0  
     elif ang > 22.5:  
       intensity = -400.0 / (45.0 - 22.5) * (ang - 45.0)  
     elif ang > 11.2:  
       intensity = (400.0 - 1600.0) / (22.5 - 11.2) * (ang - 22.5) + 400.0  
     else:  
       intensity = (1600.0 - 2000.0) / (11.2 - 0) * (ang - 11.2) + 1600.0  
     LED_FOV_map[y][x] = intensity * numpy.power(numpy.dot(v1, v2), 2) / numpy.power(numpy.linalg.norm(v2), 4)  
 head_FOV_width = 2 * max(LED_FOV_dx1, LED_FOV_dx2)  
 head_FOV_height = LED_FOV_height + (LEDs_on_head - 1) * LED_interval + shift_on_head  
 head_FOV_map = numpy.zeros((head_FOV_height, head_FOV_width))  
 print head_FOV_width  
 print head_FOV_height  
 for y in range(LED_FOV_height):  
   for x in range(LED_FOV_width):  
     for i in range(LEDs_on_head):  
       head_FOV_map[y + i * LED_interval][x] += LED_FOV_map[y][x]  
       head_FOV_map[y + i * LED_interval + shift_on_head][(head_FOV_width -1) - x] += LED_FOV_map[y][x]  
 # 380 nm to 780 nm -> RGB  
 def wave2rgb(wavelength):  
   GAMMA = 1.0  
   # ITYPE=1 - PLAIN SPECTUM  
   # ITYPE=2 - MARK SPECTRUM AT 100 nm INTEVALS  
   # ITYPE=3 - HYDROGEN BALMER EMISSION SPECTRA  
   # ITYPE=4 - HYDROGEN BALMER ABSORPTION SPECTRA  
   ITYPE = 1  
   if wavelength < 440:  
     r = -1.0 * (wavelength - 440.0) / (440.0 - 380.0)  
     g = 0  
     b = 1  
   elif wavelength < 490.0:  
     r = 0.0  
     g = (wavelength - 440.0) / (490.0 - 440.0)  
     b = 1.0  
   elif wavelength < 510.0:  
     r = 0.0  
     g = 1.0  
     b = -1.0 * (wavelength - 510.0) / (510.0 - 490.0)  
   elif wavelength < 580:  
     r = (wavelength - 510.0) / (580.0 - 510.0)  
     g = 1.0  
     b = 0.0  
   elif wavelength < 645:  
     r = 1.0  
     g = -1.0 * (wavelength - 645.0) / (645.0 - 580.0)  
     b = 0.0  
   else:  
     r = 1.0  
     g = 0.0  
     b = 0.0  
   if wavelength > 700.0:  
     sss = 0.3 + 0.7 * (780.0 - wavelength) / (780.0 - 700.0)  
   elif wavelength < 420.0:  
     sss = 0.3 + 0.7 * (wavelength - 380.0) / (420.0 - 380.0)  
   else:  
     sss = 1.0  
   # Gamma adjust and write image to an array  
   r = int(255.0 * math.pow(sss * r, GAMMA))  
   g = int(255.0 * math.pow(sss * g, GAMMA))  
   b = int(255.0 * math.pow(sss * b, GAMMA))  
   if ITYPE == 2:  
     if abs(wavelength - 400) < 1 or abs(wavelength - 500) < 1 or abs(wavelength - 600) < 1 or abs(wavelength - 700) < 1:  
       r = 255  
       g = 255  
       b = 255  
   elif ITYPE == 3:  
     if abs(wavelength-656.0) > 1.0 and abs(wavelength-486.0) > 1.0 and abs(wavelength-433.0) > 1.0 and abs(wavelength-410.0) > 1.0 and abs(wavelength-396.0) > 1.0:  
       r = 0  
       g = 0  
       b = 0  
   elif ITYPE == 4:  
     if abs(wavelength-656.0) < 1.1 or abs(wavelength-486.0) < 1.1 or abs(wavelength-433.0) < 1.1 or abs(wavelength-410.0) < 1.1 or abs(wavelength-396.0) < 1.1:  
       r = 0  
       g = 0  
       b = 0  
   return (r, g, b)  
 minvalue = maxvalue = head_FOV_map[0][0]  
 for i in range(head_FOV_height):  
   for j in range(head_FOV_width):  
     if head_FOV_map[i][j] > maxvalue:  
       maxvalue = head_FOV_map[i][j]  
     elif head_FOV_map[i][j] < minvalue:  
       minvalue = head_FOV_map[i][j]  
 print minvalue  
 print maxvalue  
 print "profile"  
 for i in range(head_FOV_height):  
   print head_FOV_map[i][head_FOV_width / 2]  
 img = Image.new('RGB', (head_FOV_width, head_FOV_height), "black")  
 #img = Image.new('L', (head_FOV_width, head_FOV_height))  
 pixels = img.load()  
 for i in range(img.size[1]):  
   for j in range(img.size[0]):  
     #pixels[j, i] = wave2rgb(head_FOV_map[i][j] / 8000.0 * 400.0 + 380.0)  
     pixels[j, i] = palette[int(round((head_FOV_map[i][j] - minvalue) / (maxvalue - minvalue) * (len(palette) - 1)))]  
     #pixels[j, i] = int(round((head_FOV_map[i][j] - minvalue) / (maxvalue - minvalue) * 255.0))  
 img.show()  

결과물


 FOV_simulation_assign_60mm_30mm



 FOV_simulation_assign_90mm_45mm


 시각적 변화를 위한 몇 가지 프로파일들


Yellow gradient

 palette=((0, 0, 0), (53, 2, 0), (53, 2, 0), (53, 3, 0), (53, 3, 0), (53, 4, 0), (52, 4, 0), (52, 5, 0), (52, 6, 0), (52, 6, 0), (51, 7, 0), (51, 8, 0), (51, 9, 0), (51, 9, 0), (51, 10, 0), (51, 10, 0), (51, 11, 0), (51, 11, 0), (51, 12, 0), (51, 12, 0), (51, 13, 0), (50, 14, 0), (50, 14, 0), (50, 15, 0), (50, 15, 0), (50, 16, 0), (50, 16, 0), (50, 17, 0), (50, 17, 0), (50, 18, 0), (50, 18, 0), (50, 19, 0), (50, 20, 0), (50, 20, 0), (50, 21, 0), (51, 21, 0), (51, 22, 0), (51, 22, 0), (51, 23, 0), (51, 24, 0), (51, 25, 0), (51, 25, 0), (52, 26, 0), (52, 27, 0), (52, 27, 0), (52, 28, 0), (52, 28, 0), (52, 29, 0), (52, 29, 0), (52, 30, 0), (53, 30, 0), (53, 31, 0), (53, 32, 0), (54, 32, 0), (54, 33, 0), (54, 33, 0), (54, 34, 0), (55, 34, 0), (55, 35, 0), (55, 35, 0), (55, 36, 0), (56, 36, 0), (56, 37, 0), (56, 38, 0), (57, 39, 0), (57, 39, 0), (57, 40, 0), (58, 41, 0), (58, 41, 0), (59, 42, 0), (59, 42, 0), (59, 43, 0), (60, 43, 0), (60, 44, 0), (61, 45, 0), (61, 45, 0), (62, 46, 0), (62, 46, 0), (63, 47, 0), (63, 47, 0), (64, 48, 0), (64, 48, 0), (64, 49, 0), (65, 50, 0), (65, 50, 0), (66, 51, 0), (66, 51, 0), (67, 52, 0), (67, 52, 0), (68, 53, 0), (69, 53, 0), (70, 54, 0), (71, 55, 0), (72, 56, 0), (72, 56, 0), (73, 57, 0), (74, 58, 0), (74, 58, 0), (75, 59, 0), (75, 59, 0), (76, 60, 0), (77, 60, 0), (78, 61, 0), (78, 61, 0), (79, 62, 0), (80, 63, 0), (80, 63, 0), (81, 64, 0), (82, 64, 0), (83, 65, 0), (84, 65, 0), (84, 66, 0), (85, 66, 0), (86, 67, 0), (87, 68, 0), (88, 68, 0), (88, 69, 0), (89, 69, 0), (90, 70, 0), (92, 71, 0), (93, 72, 0), (94, 72, 0), (94, 73, 0), (95, 73, 0), (96, 74, 0), (97, 75, 0), (98, 75, 0), (98, 76, 0), (99, 76, 0), (101, 77, 0), (102, 77, 0), (103, 78, 0), (104, 78, 0), (104, 79, 0), (105, 79, 0), (106, 80, 0), (107, 81, 0), (108, 81, 0), (109, 82, 0), (110, 82, 0), (111, 83, 0), (112, 83, 0), (114, 84, 0), (115, 84, 0), (115, 85, 0), (116, 86, 0), (117, 86, 0), (118, 87, 0), (119, 88, 0), (120, 89, 0), (122, 89, 0), (123, 90, 0), (124, 90, 0), (125, 91, 0), (126, 91, 0), (127, 92, 0), (128, 93, 0), (129, 93, 0), (130, 94, 0), (131, 94, 0), (133, 95, 0), (134, 95, 0), (135, 96, 0), (136, 96, 0), (137, 97, 0), (138, 98, 0), (139, 98, 0), (140, 99, 0), (141, 99, 0), (142, 100, 0), (143, 100, 0), (145, 101, 0), (146, 102, 0), (147, 102, 0), (148, 103, 0), (149, 104, 0), (150, 105, 0), (151, 105, 0), (152, 106, 0), (153, 106, 0), (155, 107, 0), (156, 107, 0), (158, 108, 0), (159, 108, 0), (160, 109, 0), (161, 109, 0), (162, 110, 0), (163, 111, 0), (164, 111, 0), (164, 112, 0), (165, 112, 0), (167, 113, 0), (168, 113, 0), (169, 114, 0), (170, 114, 0), (171, 115, 0), (173, 116, 0), (174, 116, 0), (175, 117, 0), (176, 117, 0), (177, 118, 0), (178, 118, 0), (179, 119, 0), (180, 120, 0), (181, 121, 0), (182, 121, 0), (183, 122, 0), (184, 123, 0), (185, 123, 0), (186, 124, 0), (187, 124, 0), (188, 125, 0), (190, 125, 0), (191, 126, 0), (192, 126, 0), (193, 127, 0), (194, 127, 0), (195, 128, 0), (195, 129, 0), (196, 129, 0), (197, 130, 0), (198, 130, 0), (200, 131, 0), (201, 131, 0), (202, 132, 0), (203, 132, 0), (204, 133, 0), (205, 134, 0), (206, 135, 0), (206, 135, 0), (207, 136, 0), (208, 137, 0), (209, 137, 0), (210, 138, 0), (211, 138, 0), (212, 139, 0), (213, 139, 0), (214, 140, 0), (215, 141, 0), (216, 141, 0), (216, 142, 0), (217, 142, 0), (218, 143, 0), (219, 143, 0), (220, 144, 0), (221, 144, 0), (221, 145, 0), (222, 145, 0), (223, 146, 0), (224, 147, 0), (224, 147, 0), (225, 148, 0), (225, 148, 0), (226, 149, 0), (227, 149, 0), (228, 150, 0), (229, 151, 0), (229, 151, 0), (230, 152, 0), (231, 153, 0), (232, 154, 0), (232, 154, 0), (233, 155, 0), (233, 155, 0), (234, 156, 0), (235, 156, 0), (236, 157, 0), (236, 157, 0), (237, 158, 0), (238, 159, 0), (238, 159, 0), (239, 160, 0), (239, 160, 0), (240, 161, 0), (240, 161, 0), (240, 162, 0), (241, 162, 0), (241, 163, 0), (241, 163, 0), (242, 164, 0), (243, 165, 0), (243, 165, 0), (244, 166, 0), (244, 167, 0), (245, 168, 0), (245, 168, 0), (246, 169, 0), (246, 169, 0), (247, 170, 0), (247, 171, 0), (248, 171, 0), (248, 172, 0), (248, 172, 0), (248, 173, 0), (249, 173, 0), (249, 174, 0), (249, 174, 0), (249, 175, 0), (250, 175, 0), (250, 176, 0), (250, 177, 0), (251, 177, 0), (251, 178, 0), (251, 178, 0), (251, 179, 0), (252, 179, 0), (252, 180, 0), (252, 180, 0), (252, 181, 0), (252, 181, 0), (252, 182, 0), (252, 183, 0), (253, 184, 0), (253, 184, 0), (253, 185, 0), (253, 186, 0), (253, 186, 0), (253, 187, 0), (253, 187, 0), (253, 188, 0), (254, 189, 0), (254, 189, 0), (254, 190, 0), (254, 190, 0), (254, 191, 0), (254, 191, 0), (254, 192, 0), (254, 192, 0), (254, 193, 0), (254, 193, 0), (254, 194, 0), (254, 195, 0), (254, 195, 0), (254, 196, 0), (254, 196, 0), (254, 197, 0), (254, 197, 0), (254, 198, 0), (253, 199, 0), (253, 200, 0), (253, 200, 0), (253, 201, 0), (253, 202, 0), (253, 202, 0), (253, 203, 0), (252, 203, 0), (252, 204, 0), (252, 204, 0), (252, 205, 0), (252, 205, 0), (252, 206, 0), (252, 207, 0), (251, 207, 0), (251, 208, 0), (251, 208, 0), (251, 209, 0), (250, 209, 0), (250, 210, 0), (250, 210, 0), (250, 211, 0), (250, 211, 0), (250, 212, 0), (250, 213, 0), (249, 213, 0), (249, 214, 0), (249, 214, 0), (249, 215, 0), (248, 216, 0), (248, 217, 0), (248, 217, 0), (248, 218, 0), (247, 218, 0), (247, 219, 0), (247, 220, 0), (246, 220, 0), (246, 221, 0), (246, 221, 0), (246, 222, 0), (245, 222, 0), (245, 223, 0), (245, 223, 0), (245, 224, 0), (244, 225, 0), (244, 225, 0), (244, 226, 0), (243, 226, 0), (243, 227, 0), (243, 227, 0), (242, 228, 0), (242, 228, 0), (241, 229, 0), (241, 230, 0), (241, 230, 0), (240, 231, 0), (240, 232, 0), (240, 233, 0), (239, 233, 0), (239, 234, 0), (239, 234, 0), (239, 235, 0), (238, 235, 0), (238, 236, 0), (238, 236, 0), (237, 237, 0), (237, 238, 0), (237, 238, 0), (237, 239, 0), (236, 239, 0), (236, 240, 0), (236, 240, 0), (235, 241, 0), (235, 241, 0), (234, 242, 0), (234, 243, 0), (233, 243, 0), (233, 244, 0), (233, 244, 0), (233, 245, 0), (232, 245, 0), (232, 246, 0), (232, 247, 0), (232, 247, 0), (231, 248, 0), (231, 249, 0), (231, 250, 0), (230, 250, 0), (230, 251, 0), (230, 251, 0), (230, 252, 0), (229, 252, 0), (229, 253, 0), (229, 253, 0), (229, 254, 0), (229, 254, 0)) 


Glowbow gradient


 palette =((0, 0, 0), (2, 0, 0), (4, 1, 1), (6, 1, 1), (8, 1, 1), (10, 1, 2), (12, 2, 2), (13, 2, 3), (15, 2, 3), (17, 2, 3), (19, 2, 4), (21, 2, 4), (23, 2, 4), (24, 3, 5), (26, 3, 5), (28, 3, 5), (30, 3, 6), (32, 4, 6), (34, 4, 7), (35, 4, 7), (37, 4, 7), (39, 5, 8), (41, 5, 8), (43, 5, 8), (45, 5, 9), (47, 5, 9), (49, 5, 9), (51, 5, 9), (53, 6, 10), (55, 6, 10), (57, 6, 10), (59, 7, 11), (60, 7, 12), (62, 7, 12), (64, 7, 12), (66, 8, 13), (67, 8, 13), (69, 8, 13), (71, 8, 13), (73, 8, 14), (75, 8, 14), (77, 8, 14), (79, 9, 15), (81, 9, 16), (83, 9, 16), (85, 9, 16), (88, 10, 17), (91, 10, 17), (94, 10, 17), (97, 11, 18), (100, 11, 19), (103, 12, 20), (105, 12, 20), (106, 12, 21), (108, 12, 21), (110, 12, 21), (112, 12, 21), (113, 13, 22), (115, 13, 22), (117, 13, 22), (119, 13, 22), (121, 14, 23), (123, 14, 23), (125, 14, 24), (127, 15, 24), (129, 15, 25), (131, 15, 25), (133, 15, 25), (135, 15, 26), (136, 15, 26), (138, 15, 26), (140, 15, 26), (142, 16, 27), (144, 16, 27), (146, 16, 28), (147, 17, 28), (149, 17, 29), (151, 17, 29), (153, 17, 29), (155, 18, 30), (157, 18, 30), (159, 18, 30), (160, 18, 30), (162, 18, 31), (164, 18, 31), (166, 18, 32), (168, 19, 32), (170, 19, 33), (172, 19, 33), (174, 19, 33), (176, 20, 34), (178, 20, 34), (180, 20, 34), (182, 21, 35), (183, 21, 35), (185, 21, 35), (187, 21, 35), (189, 21, 36), (190, 21, 36), (192, 21, 36), (194, 21, 37), (196, 22, 37), (198, 22, 38), (200, 22, 38), (202, 23, 39), (204, 23, 39), (205, 23, 39), (206, 24, 39), (206, 24, 38), (207, 25, 38), (207, 26, 38), (207, 26, 37), (208, 27, 37), (208, 28, 36), (209, 29, 36), (209, 29, 35), (210, 30, 35), (210, 30, 35), (211, 31, 35), (211, 31, 34), (212, 32, 34), (212, 33, 34), (212, 33, 33), (213, 34, 33), (213, 35, 32), (214, 36, 32), (214, 36, 31), (215, 37, 31), (215, 37, 31), (216, 38, 31), (216, 38, 30), (217, 39, 30), (217, 39, 30), (217, 40, 30), (218, 40, 29), (218, 41, 29), (219, 42, 28), (219, 43, 28), (220, 44, 27), (220, 44, 27), (221, 45, 27), (221, 45, 26), (222, 46, 26), (222, 46, 26), (222, 47, 26), (223, 48, 25), (223, 48, 25), (224, 49, 24), (224, 50, 24), (225, 51, 23), (225, 51, 23), (226, 52, 23), (226, 52, 22), (227, 53, 22), (227, 53, 22), (228, 54, 21), (228, 55, 21), (228, 55, 21), (229, 56, 21), (229, 57, 20), (230, 58, 20), (230, 58, 20), (231, 59, 19), (231, 59, 19), (232, 60, 18), (232, 61, 18), (233, 61, 17), (233, 62, 17), (233, 62, 17), (234, 63, 17), (234, 63, 16), (235, 64, 16), (235, 65, 16), (236, 65, 15), (236, 66, 15), (237, 67, 14), (237, 68, 14), (238, 68, 13), (238, 69, 13), (238, 69, 13), (239, 70, 13), (239, 70, 12), (240, 71, 12), (240, 72, 12), (241, 72, 11), (241, 73, 11), (242, 74, 10), (242, 75, 10), (243, 75, 9), (243, 76, 9), (243, 76, 9), (244, 77, 9), (244, 77, 8), (245, 78, 8), (245, 78, 8), (246, 79, 8), (247, 80, 7), (247, 80, 7), (247, 81, 6), (248, 82, 6), (248, 83, 5), (248, 83, 5), (249, 84, 5), (249, 84, 4), (250, 85, 4), (250, 85, 4), (251, 86, 4), (252, 87, 3), (252, 87, 3), (252, 88, 2), (253, 89, 2), (253, 90, 1), (253, 90, 1), (254, 91, 1), (254, 91, 0), (255, 92, 0), (255, 93, 0), (255, 94, 0), (255, 95, 0), (255, 96, 0), (255, 97, 0), (255, 98, 0), (255, 100, 0), (255, 101, 0), (255, 102, 0), (255, 103, 0), (255, 105, 0), (255, 106, 0), (255, 107, 0), (255, 108, 0), (255, 109, 0), (255, 110, 0), (255, 111, 0), (255, 113, 0), (255, 114, 0), (255, 115, 0), (255, 116, 0), (255, 117, 0), (255, 118, 0), (255, 119, 0), (255, 120, 0), (255, 121, 0), (255, 123, 0), (255, 124, 0), (255, 126, 0), (255, 127, 0), (255, 128, 0), (255, 129, 0), (255, 130, 0), (255, 131, 0), (255, 132, 0), (255, 133, 0), (255, 134, 0), (255, 136, 0), (255, 137, 0), (255, 138, 0), (255, 139, 0), (255, 140, 0), (255, 141, 0), (255, 142, 0), (255, 143, 0), (255, 145, 0), (255, 146, 0), (255, 147, 0), (255, 149, 0), (255, 150, 0), (255, 151, 0), (255, 152, 0), (255, 153, 0), (255, 154, 0), (255, 155, 0), (255, 156, 0), (255, 157, 0), (255, 158, 0), (255, 160, 0), (255, 161, 0), (255, 162, 0), (255, 163, 0), (255, 164, 0), (255, 166, 0), (255, 167, 0), (255, 168, 0), (255, 169, 0), (255, 170, 0), (255, 172, 0), (255, 173, 0), (255, 174, 0), (255, 175, 0), (255, 176, 0), (255, 177, 0), (255, 178, 0), (255, 179, 0), (255, 180, 0), (255, 181, 0), (255, 182, 0), (255, 184, 0), (255, 185, 0), (255, 186, 0), (255, 188, 0), (255, 189, 0), (255, 190, 0), (255, 191, 0), (255, 192, 0), (255, 193, 0), (255, 194, 0), (255, 196, 0), (255, 197, 0), (255, 198, 0), (255, 199, 0), (255, 200, 0), (255, 201, 0), (255, 202, 0), (255, 203, 0), (255, 204, 0), (255, 206, 0), (255, 207, 0), (255, 208, 0), (255, 210, 0), (255, 211, 0), (255, 212, 0), (255, 213, 0), (255, 214, 0), (255, 215, 0), (255, 216, 0), (255, 217, 0), (255, 218, 1), (255, 218, 3), (255, 219, 5), (255, 219, 8), (255, 219, 10), (255, 219, 12), (255, 220, 15), (255, 220, 17), (255, 221, 20), (255, 221, 22), (255, 222, 24), (255, 222, 26), (255, 222, 29), (255, 223, 31), (255, 223, 34), (255, 223, 36), (255, 224, 38), (255, 224, 40), (255, 224, 43), (255, 224, 45), (255, 225, 47), (255, 225, 50), (255, 225, 52), (255, 226, 55), (255, 226, 57), (255, 227, 60), (255, 227, 62), (255, 228, 64), (255, 228, 66), (255, 228, 69), (255, 228, 71), (255, 229, 73), (255, 229, 75), (255, 229, 78), (255, 229, 80), (255, 230, 82), (255, 230, 85), (255, 231, 87), (255, 231, 90), (255, 232, 92), (255, 232, 95), (255, 232, 97), (255, 233, 99), (255, 233, 101), (255, 233, 104), (255, 233, 106), (255, 234, 109), (255, 234, 111), (255, 234, 113), (255, 235, 115), (255, 235, 118), (255, 235, 120), (255, 236, 122), (255, 236, 125), (255, 237, 127), (255, 237, 130), (255, 237, 132), (255, 238, 134), (255, 238, 136), (255, 238, 138), (255, 239, 141), (255, 239, 143), (255, 239, 145), (255, 239, 148), (255, 240, 150), (255, 240, 153), (255, 240, 155), (255, 240, 157), (255, 241, 159), (255, 241, 161), (255, 242, 164), (255, 242, 166), (255, 243, 169), (255, 243, 171), (255, 243, 174), (255, 244, 176), (255, 244, 179), (255, 244, 181), (255, 245, 183), (255, 245, 185), (255, 245, 187), (255, 245, 190), (255, 246, 192), (255, 246, 194), (255, 246, 196), (255, 247, 199), (255, 247, 201), (255, 248, 204), (255, 248, 206), (255, 249, 209), (255, 249, 211), (255, 249, 214), (255, 249, 216), (255, 250, 218), (255, 250, 220), (255, 250, 223), (255, 250, 225), (255, 251, 228), (255, 251, 230), (255, 252, 232), (255, 252, 234), (255, 253, 237), (255, 253, 239), (255, 253, 241), (255, 254, 244), (255, 254, 246), (255, 254, 249), (255, 254, 251), (255, 255, 253)) 


gray gradient


 palette=((1, 1, 1), (1, 1, 1), (2, 2, 2), (2, 2, 2), (3, 3, 3), (3, 3, 3), (4, 4, 4), (4, 4, 4), (5, 5, 5), (5, 5, 5), (6, 6, 6), (7, 7, 7), (8, 8, 8), (9, 9, 9), (9, 9, 9), (10, 10, 10), (10, 10, 10), (11, 11, 11), (11, 11, 11), (12, 12, 12), (13, 13, 13), (13, 13, 13), (14, 14, 14), (14, 14, 14), (15, 15, 15), (15, 15, 15), (16, 16, 16), (16, 16, 16), (17, 17, 17), (17, 17, 17), (18, 18, 18), (19, 19, 19), (19, 19, 19), (20, 20, 20), (21, 21, 21), (22, 22, 22), (22, 22, 22), (23, 23, 23), (23, 23, 23), (24, 24, 24), (24, 24, 24), (25, 25, 25), (26, 26, 26), (26, 26, 26), (27, 27, 27), (27, 27, 27), (28, 28, 28), (28, 28, 28), (29, 29, 29), (29, 29, 29), (30, 30, 30), (31, 31, 31), (31, 31, 31), (32, 32, 32), (32, 32, 32), (33, 33, 33), (33, 33, 33), (34, 34, 34), (35, 35, 35), (35, 35, 35), (36, 36, 36), (37, 37, 37), (38, 38, 38), (38, 38, 38), (39, 39, 39), (39, 39, 39), (40, 40, 40), (40, 40, 40), (41, 41, 41), (41, 41, 41), (42, 42, 42), (42, 42, 42), (43, 43, 43), (44, 44, 44), (44, 44, 44), (45, 45, 45), (45, 45, 45), (46, 46, 46), (46, 46, 46), (47, 47, 47), (47, 47, 47), (48, 48, 48), (49, 49, 49), (49, 49, 49), (50, 50, 50), (51, 51, 51), (52, 52, 52), (52, 52, 52), (53, 53, 53), (53, 53, 53), (54, 54, 54), (54, 54, 54), (55, 55, 55), (56, 56, 56), (56, 56, 56), (57, 57, 57), (57, 57, 57), (58, 58, 58), (58, 58, 58), (59, 59, 59), (59, 59, 59), (60, 60, 60), (60, 60, 60), (61, 61, 61), (62, 62, 62), (62, 62, 62), (63, 63, 63), (64, 64, 64), (65, 65, 65), (65, 65, 65), (66, 66, 66), (66, 66, 66), (67, 67, 67), (68, 68, 68), (68, 68, 68), (69, 69, 69), (69, 69, 69), (70, 70, 70), (70, 70, 70), (71, 71, 71), (71, 71, 71), (72, 72, 72), (72, 72, 72), (73, 73, 73), (74, 74, 74), (74, 74, 74), (75, 75, 75), (75, 75, 75), (76, 76, 76), (76, 76, 76), (77, 77, 77), (78, 78, 78), (78, 78, 78), (79, 79, 79), (80, 80, 80), (81, 81, 81), (81, 81, 81), (82, 82, 82), (82, 82, 82), (83, 83, 83), (83, 83, 83), (84, 84, 84), (84, 84, 84), (85, 85, 85), (86, 86, 86), (86, 86, 86), (87, 87, 87), (87, 87, 87), (88, 88, 88), (88, 88, 88), (89, 89, 89), (89, 89, 89), (90, 90, 90), (91, 91, 91), (92, 92, 92), (92, 92, 92), (93, 93, 93), (94, 94, 94), (94, 94, 94), (95, 95, 95), (95, 95, 95), (96, 96, 96), (96, 96, 96), (97, 97, 97), (98, 98, 98), (98, 98, 98), (99, 99, 99), (99, 99, 99), (100, 100, 100), (100, 100, 100), (101, 101, 101), (101, 101, 101), (102, 102, 102), (102, 102, 102), (103, 103, 103), (104, 104, 104), (104, 104, 104), (105, 105, 105), (105, 105, 105), (106, 106, 106), (107, 107, 107), (108, 108, 108), (108, 108, 108), (109, 109, 109), (109, 109, 109), (110, 110, 110), (111, 111, 111), (111, 111, 111), (112, 112, 112), (112, 112, 112), (113, 113, 113), (113, 113, 113), (114, 114, 114), (114, 114, 114), (115, 115, 115), (116, 116, 116), (116, 116, 116), (117, 117, 117), (117, 117, 117), (118, 118, 118), (118, 118, 118), (119, 119, 119), (119, 119, 119), (120, 120, 120), (121, 121, 121), (121, 121, 121), (122, 122, 122), (123, 123, 123), (124, 124, 124), (124, 124, 124), (125, 125, 125), (125, 125, 125), (126, 126, 126), (126, 126, 126), (127, 127, 127), (127, 127, 127), (128, 128, 128), (129, 129, 129), (129, 129, 129), (130, 130, 130), (130, 130, 130), (131, 131, 131), (131, 131, 131), (132, 132, 132), (132, 132, 132), (133, 133, 133), (134, 134, 134), (135, 135, 135), (135, 135, 135), (136, 136, 136), (137, 137, 137), (137, 137, 137), (138, 138, 138), (138, 138, 138), (139, 139, 139), (139, 139, 139), (140, 140, 140), (141, 141, 141), (141, 141, 141), (142, 142, 142), (142, 142, 142), (143, 143, 143), (143, 143, 143), (144, 144, 144), (144, 144, 144), (145, 145, 145), (145, 145, 145), (146, 146, 146), (147, 147, 147), (147, 147, 147), (148, 148, 148), (148, 148, 148), (149, 149, 149), (150, 150, 150), (151, 151, 151), (151, 151, 151), (152, 152, 152), (153, 153, 153), (153, 153, 153), (154, 154, 154), (154, 154, 154), (155, 155, 155), (155, 155, 155), (156, 156, 156), (156, 156, 156), (157, 157, 157), (157, 157, 157), (158, 158, 158), (159, 159, 159), (159, 159, 159), (160, 160, 160), (160, 160, 160), (161, 161, 161), (161, 161, 161), (162, 162, 162), (162, 162, 162), (163, 163, 163), (164, 164, 164), (165, 165, 165), (165, 165, 165), (166, 166, 166), (167, 167, 167), (167, 167, 167), (168, 168, 168), (168, 168, 168), (169, 169, 169), (169, 169, 169), (170, 170, 170), (171, 171, 171), (171, 171, 171), (172, 172, 172), (172, 172, 172), (173, 173, 173), (173, 173, 173), (174, 174, 174), (174, 174, 174), (175, 175, 175), (175, 175, 175), (176, 176, 176), (177, 177, 177), (178, 178, 178), (178, 178, 178), (179, 179, 179), (180, 180, 180), (180, 180, 180), (181, 181, 181), (181, 181, 181), (182, 182, 182), (182, 182, 182), (183, 183, 183), (184, 184, 184), (184, 184, 184), (185, 185, 185), (185, 185, 185), (186, 186, 186), (186, 186, 186), (187, 187, 187), (187, 187, 187), (188, 188, 188), (189, 189, 189), (189, 189, 189), (190, 190, 190), (190, 190, 190), (191, 191, 191), (191, 191, 191), (192, 192, 192), (193, 193, 193), (194, 194, 194), (194, 194, 194), (195, 195, 195), (196, 196, 196), (196, 196, 196), (197, 197, 197), (197, 197, 197), (198, 198, 198), (198, 198, 198), (199, 199, 199), (199, 199, 199), (200, 200, 200), (200, 200, 200), (201, 201, 201), (202, 202, 202), (202, 202, 202), (203, 203, 203), (203, 203, 203), (204, 204, 204), (204, 204, 204), (205, 205, 205), (206, 206, 206), (207, 207, 207), (208, 208, 208), (208, 208, 208), (209, 209, 209), (209, 209, 209), (210, 210, 210), (210, 210, 210), (211, 211, 211), (211, 211, 211), (212, 212, 212), (212, 212, 212), (213, 213, 213), (214, 214, 214), (214, 214, 214), (215, 215, 215), (215, 215, 215), (216, 216, 216), (216, 216, 216), (217, 217, 217), (217, 217, 217), (218, 218, 218), (218, 218, 218), (219, 219, 219), (220, 220, 220), (221, 221, 221), (221, 221, 221), (222, 222, 222), (223, 223, 223), (223, 223, 223), (224, 224, 224), (224, 224, 224), (225, 225, 225), (226, 226, 226), (226, 226, 226), (227, 227, 227), (227, 227, 227), (228, 228, 228), (228, 228, 228), (229, 229, 229), (229, 229, 229), (230, 230, 230), (230, 230, 230), (231, 231, 231), (232, 232, 232), (232, 232, 232), (233, 233, 233), (233, 233, 233), (234, 234, 234), (234, 234, 234), (235, 235, 235), (236, 236, 236), (237, 237, 237), (237, 237, 237), (238, 238, 238), (239, 239, 239), (239, 239, 239), (240, 240, 240), (240, 240, 240), (241, 241, 241), (241, 241, 241), (242, 242, 242), (242, 242, 242), (243, 243, 243), (244, 244, 244), (244, 244, 244), (245, 245, 245), (245, 245, 245), (246, 246, 246), (246, 246, 246), (247, 247, 247), (248, 248, 248), (248, 248, 248), (249, 249, 249), (250, 250, 250), (251, 251, 251), (251, 251, 251), (252, 252, 252), (252, 252, 252), (253, 253, 253), (253, 253, 253), (254, 254, 254), (254, 254, 254), (254, 254, 254), (255, 255, 255)) 


Iron gradient




 palette=((0, 0, 0), (0, 0, 10), (0, 0, 20), (0, 0, 30), (0, 0, 37), (0, 0, 42), (0, 0, 46), (0, 0, 50), (0, 0, 54), (0, 0, 58), (0, 0, 62), (0, 0, 66), (0, 0, 70), (0, 0, 74), (0, 0, 79), (0, 0, 82), (1, 0, 85), (1, 0, 87), (2, 0, 89), (2, 0, 92), (3, 0, 94), (4, 0, 97), (4, 0, 99), (5, 0, 101), (6, 0, 103), (7, 0, 105), (8, 0, 107), (9, 0, 110), (10, 0, 112), (11, 0, 115), (12, 0, 116), (13, 0, 117), (13, 0, 118), (14, 0, 119), (16, 0, 120), (18, 0, 121), (19, 0, 123), (21, 0, 124), (23, 0, 125), (25, 0, 126), (27, 0, 128), (28, 0, 129), (30, 0, 131), (32, 0, 132), (34, 0, 133), (36, 0, 134), (38, 0, 135), (40, 0, 137), (42, 0, 137), (44, 0, 138), (46, 0, 139), (48, 0, 140), (50, 0, 141), (52, 0, 142), (54, 0, 142), (56, 0, 143), (57, 0, 144), (59, 0, 145), (60, 0, 146), (62, 0, 147), (63, 0, 147), (65, 0, 148), (66, 0, 149), (68, 0, 149), (69, 0, 150), (71, 0, 150), (73, 0, 150), (74, 0, 150), (76, 0, 151), (78, 0, 151), (79, 0, 151), (81, 0, 151), (82, 0, 152), (84, 0, 152), (86, 0, 152), (88, 0, 153), (90, 0, 153), (92, 0, 153), (93, 0, 154), (95, 0, 154), (97, 0, 155), (99, 0, 155), (100, 0, 155), (102, 0, 155), (104, 0, 155), (106, 0, 155), (108, 0, 156), (109, 0, 156), (111, 0, 156), (112, 0, 156), (113, 0, 157), (115, 0, 157), (117, 0, 157), (119, 0, 157), (120, 0, 157), (122, 0, 157), (124, 0, 157), (126, 0, 157), (127, 0, 157), (129, 0, 157), (131, 0, 157), (132, 0, 157), (134, 0, 157), (135, 0, 157), (137, 0, 157), (138, 0, 157), (139, 0, 157), (141, 0, 157), (143, 0, 156), (145, 0, 156), (147, 0, 156), (149, 0, 156), (150, 0, 155), (152, 0, 155), (153, 0, 155), (155, 0, 155), (156, 0, 155), (157, 0, 155), (159, 0, 155), (160, 0, 155), (162, 0, 155), (163, 0, 155), (164, 0, 155), (166, 0, 154), (167, 0, 154), (168, 0, 154), (169, 0, 153), (170, 0, 153), (171, 0, 153), (173, 0, 153), (174, 1, 152), (175, 1, 152), (176, 1, 152), (176, 1, 152), (177, 1, 151), (178, 1, 151), (179, 1, 150), (180, 2, 150), (181, 2, 149), (182, 2, 149), (183, 3, 149), (184, 3, 149), (185, 4, 149), (186, 4, 149), (186, 4, 148), (187, 5, 147), (188, 5, 147), (189, 5, 147), (190, 6, 146), (191, 6, 146), (191, 6, 146), (192, 7, 145), (192, 7, 145), (193, 8, 144), (193, 9, 144), (194, 10, 143), (195, 10, 142), (195, 11, 142), (196, 12, 141), (197, 12, 140), (198, 13, 139), (198, 14, 138), (199, 15, 137), (200, 16, 136), (201, 17, 135), (202, 18, 134), (202, 19, 133), (203, 19, 133), (203, 20, 132), (204, 21, 130), (205, 22, 129), (206, 23, 128), (206, 24, 126), (207, 24, 124), (207, 25, 123), (208, 26, 121), (209, 27, 120), (209, 28, 118), (210, 28, 117), (210, 29, 116), (211, 30, 114), (211, 32, 113), (212, 33, 111), (212, 34, 110), (213, 35, 107), (213, 36, 105), (214, 37, 103), (215, 38, 101), (216, 39, 100), (216, 40, 98), (217, 42, 96), (218, 43, 94), (218, 44, 92), (219, 46, 90), (219, 47, 87), (220, 47, 84), (221, 48, 81), (221, 49, 78), (222, 50, 74), (222, 51, 71), (223, 52, 68), (223, 53, 65), (223, 54, 61), (224, 55, 58), (224, 56, 55), (224, 57, 51), (225, 58, 48), (226, 59, 45), (226, 60, 42), (227, 61, 38), (227, 62, 35), (228, 63, 32), (228, 65, 29), (228, 66, 28), (229, 67, 27), (229, 68, 25), (229, 69, 24), (230, 70, 22), (231, 71, 21), (231, 72, 20), (231, 73, 19), (232, 74, 18), (232, 76, 16), (232, 76, 15), (233, 77, 14), (233, 77, 13), (234, 78, 12), (234, 79, 12), (235, 80, 11), (235, 81, 10), (235, 82, 10), (235, 83, 9), (236, 84, 9), (236, 86, 8), (236, 87, 8), (236, 88, 8), (237, 89, 7), (237, 90, 7), (237, 91, 6), (238, 92, 6), (238, 92, 5), (238, 93, 5), (238, 94, 5), (239, 95, 4), (239, 96, 4), (239, 97, 4), (239, 98, 4), (240, 99, 3), (240, 100, 3), (240, 101, 3), (241, 102, 3), (241, 102, 3), (241, 103, 3), (241, 104, 3), (241, 105, 2), (241, 106, 2), (241, 107, 2), (241, 107, 2), (242, 108, 1), (242, 109, 1), (242, 110, 1), (243, 111, 1), (243, 112, 1), (243, 113, 1), (243, 114, 1), (244, 115, 0), (244, 116, 0), (244, 117, 0), (244, 118, 0), (244, 119, 0), (244, 120, 0), (244, 122, 0), (245, 123, 0), (245, 124, 0), (245, 126, 0), (245, 127, 0), (246, 128, 0), (246, 129, 0), (246, 130, 0), (247, 131, 0), (247, 132, 0), (247, 133, 0), (247, 134, 0), (248, 135, 0), (248, 136, 0), (248, 136, 0), (248, 137, 0), (248, 138, 0), (248, 139, 0), (248, 140, 0), (249, 141, 0), (249, 141, 0), (249, 142, 0), (249, 143, 0), (249, 144, 0), (249, 145, 0), (249, 146, 0), (249, 147, 0), (250, 148, 0), (250, 149, 0), (250, 150, 0), (251, 152, 0), (251, 153, 0), (251, 154, 0), (251, 156, 0), (252, 157, 0), (252, 159, 0), (252, 160, 0), (252, 161, 0), (253, 162, 0), (253, 163, 0), (253, 164, 0), (253, 166, 0), (253, 167, 0), (253, 168, 0), (253, 170, 0), (253, 171, 0), (253, 172, 0), (253, 173, 0), (253, 174, 0), (254, 175, 0), (254, 176, 0), (254, 177, 0), (254, 178, 0), (254, 179, 0), (254, 180, 0), (254, 181, 0), (254, 182, 0), (254, 184, 0), (254, 185, 0), (254, 185, 0), (254, 186, 0), (254, 187, 0), (254, 188, 0), (254, 189, 0), (254, 190, 0), (254, 192, 0), (254, 193, 0), (254, 194, 0), (254, 195, 0), (254, 196, 0), (254, 197, 0), (254, 198, 0), (254, 199, 0), (254, 200, 0), (254, 201, 1), (254, 202, 1), (254, 202, 1), (254, 203, 1), (254, 204, 2), (254, 205, 2), (254, 206, 3), (254, 207, 4), (254, 207, 4), (254, 208, 5), (254, 209, 6), (254, 211, 8), (254, 212, 9), (254, 213, 10), (254, 214, 10), (254, 215, 11), (254, 216, 12), (254, 217, 13), (255, 218, 14), (255, 218, 14), (255, 219, 16), (255, 220, 18), (255, 220, 20), (255, 221, 22), (255, 222, 25), (255, 222, 27), (255, 223, 30), (255, 224, 32), (255, 225, 34), (255, 226, 36), (255, 226, 38), (255, 227, 40), (255, 228, 43), (255, 228, 46), (255, 229, 49), (255, 230, 53), (255, 230, 56), (255, 231, 60), (255, 232, 63), (255, 233, 67), (255, 234, 70), (255, 235, 73), (255, 235, 77), (255, 236, 80), (255, 237, 84), (255, 238, 87), (255, 238, 91), (255, 238, 95), (255, 239, 99), (255, 239, 103), (255, 240, 106), (255, 240, 110), (255, 241, 114), (255, 241, 119), (255, 241, 123), (255, 242, 128), (255, 242, 133), (255, 242, 138), (255, 243, 142), (255, 244, 146), (255, 244, 150), (255, 244, 154), (255, 245, 158), (255, 245, 162), (255, 245, 166), (255, 246, 170), (255, 246, 175), (255, 247, 179), (255, 247, 182), (255, 248, 186), (255, 248, 189), (255, 248, 193), (255, 248, 196), (255, 249, 199), (255, 249, 202), (255, 249, 205), (255, 250, 209), (255, 250, 212), (255, 251, 216), (255, 252, 219), (255, 252, 223), (255, 253, 226), (255, 253, 229), (255, 253, 232), (255, 254, 235), (255, 254, 238), (255, 254, 241), (255, 254, 244), (255, 255, 246)) 


Rainbow gradient


 palette=((0, 0, 0), (4, 0, 4), (8, 0, 8), (12, 0, 12), (17, 0, 17), (21, 0, 21), (25, 0, 25), (30, 0, 30), (34, 0, 34), (39, 0, 39), (43, 0, 43), (47, 0, 47), (52, 0, 52), (56, 0, 56), (60, 0, 60), (65, 0, 65), (69, 0, 69), (74, 0, 74), (78, 0, 78), (82, 0, 82), (87, 0, 87), (91, 0, 91), (96, 0, 96), (100, 0, 100), (104, 0, 104), (109, 0, 109), (113, 0, 113), (118, 0, 118), (122, 0, 122), (126, 0, 126), (131, 0, 131), (135, 0, 135), (139, 0, 139), (144, 0, 144), (148, 0, 148), (153, 0, 153), (157, 0, 157), (161, 0, 161), (166, 0, 166), (170, 0, 170), (175, 0, 175), (179, 0, 179), (183, 0, 183), (188, 0, 188), (192, 0, 192), (197, 0, 197), (201, 0, 201), (205, 0, 205), (210, 0, 210), (214, 0, 214), (218, 0, 218), (223, 0, 223), (227, 0, 227), (232, 0, 232), (236, 0, 236), (240, 0, 240), (245, 0, 245), (249, 0, 249), (254, 0, 254), (252, 0, 254), (248, 0, 253), (243, 0, 251), (239, 0, 250), (235, 0, 249), (230, 0, 247), (226, 0, 246), (221, 0, 244), (217, 0, 243), (213, 0, 242), (208, 0, 240), (204, 0, 239), (199, 0, 238), (195, 0, 237), (191, 0, 236), (186, 0, 235), (182, 0, 233), (178, 0, 232), (173, 0, 230), (169, 0, 229), (164, 0, 228), (160, 0, 226), (156, 0, 225), (151, 0, 224), (147, 0, 223), (142, 0, 222), (138, 0, 220), (134, 0, 219), (129, 0, 218), (125, 0, 216), (121, 0, 215), (116, 0, 214), (112, 0, 212), (107, 0, 211), (103, 0, 210), (99, 0, 209), (94, 0, 208), (90, 0, 206), (85, 0, 205), (81, 0, 204), (77, 0, 202), (72, 0, 201), (68, 0, 200), (63, 0, 198), (59, 0, 197), (55, 0, 196), (50, 0, 195), (46, 0, 194), (42, 0, 192), (37, 0, 191), (33, 0, 190), (28, 0, 188), (24, 0, 187), (20, 0, 185), (15, 0, 184), (11, 0, 183), (7, 0, 182), (3, 0, 181), (0, 1, 180), (0, 5, 181), (0, 9, 183), (0, 14, 184), (0, 18, 185), (0, 22, 186), (0, 27, 188), (0, 31, 189), (0, 36, 190), (0, 40, 192), (0, 44, 193), (0, 49, 194), (0, 53, 196), (0, 57, 197), (0, 62, 198), (0, 66, 199), (0, 71, 200), (0, 75, 202), (0, 79, 203), (0, 84, 204), (0, 88, 206), (0, 93, 207), (0, 97, 208), (0, 101, 210), (0, 106, 211), (0, 110, 212), (0, 114, 213), (0, 119, 214), (0, 123, 216), (0, 128, 217), (0, 132, 219), (0, 136, 220), (0, 141, 221), (0, 145, 223), (0, 150, 224), (0, 154, 225), (0, 158, 226), (0, 163, 227), (0, 167, 229), (0, 172, 230), (0, 176, 231), (0, 180, 233), (0, 185, 234), (0, 189, 235), (0, 193, 237), (0, 198, 238), (0, 202, 239), (0, 207, 240), (0, 211, 241), (0, 215, 243), (0, 220, 244), (0, 224, 245), (0, 229, 247), (0, 233, 248), (0, 237, 249), (0, 242, 251), (0, 246, 252), (0, 250, 254), (0, 255, 255), (0, 252, 251), (0, 250, 246), (0, 247, 242), (0, 244, 238), (0, 242, 233), (0, 239, 229), (0, 237, 224), (0, 234, 220), (0, 232, 216), (0, 229, 211), (0, 227, 207), (0, 224, 203), (0, 222, 198), (0, 220, 194), (0, 217, 189), (0, 215, 185), (0, 212, 181), (0, 210, 176), (0, 207, 172), (0, 205, 167), (0, 202, 163), (0, 200, 159), (0, 197, 154), (0, 195, 150), (0, 192, 146), (0, 190, 141), (0, 187, 137), (0, 185, 132), (0, 183, 128), (0, 180, 124), (0, 178, 119), (0, 175, 115), (0, 173, 110), (0, 170, 106), (0, 168, 102), (0, 165, 97), (0, 163, 93), (0, 160, 88), (0, 158, 84), (0, 155, 80), (0, 153, 75), (0, 150, 71), (0, 148, 67), (0, 146, 62), (0, 143, 58), (0, 141, 53), (0, 138, 49), (0, 136, 45), (0, 133, 40), (0, 131, 36), (0, 128, 31), (0, 126, 27), (0, 123, 23), (0, 121, 18), (0, 118, 14), (0, 116, 10), (0, 113, 6), (0, 111, 2), (3, 111, 0), (7, 114, 0), (11, 116, 0), (15, 118, 0), (19, 120, 0), (23, 123, 0), (27, 125, 0), (31, 128, 0), (35, 130, 0), (40, 132, 0), (44, 134, 0), (48, 137, 0), (52, 139, 0), (56, 142, 0), (60, 144, 0), (64, 146, 0), (68, 148, 0), (72, 151, 0), (77, 153, 0), (81, 155, 0), (85, 158, 0), (89, 160, 0), (93, 163, 0), (97, 165, 0), (101, 167, 0), (105, 169, 0), (109, 172, 0), (114, 174, 0), (118, 177, 0), (122, 179, 0), (126, 181, 0), (130, 183, 0), (134, 186, 0), (138, 188, 0), (142, 190, 0), (146, 193, 0), (151, 195, 0), (155, 198, 0), (159, 200, 0), (163, 202, 0), (167, 204, 0), (171, 207, 0), (175, 209, 0), (179, 212, 0), (184, 214, 0), (188, 216, 0), (192, 218, 0), (196, 221, 0), (200, 223, 0), (204, 225, 0), (208, 228, 0), (212, 230, 0), (216, 232, 0), (221, 235, 0), (225, 237, 0), (229, 239, 0), (233, 242, 0), (237, 244, 0), (241, 247, 0), (245, 249, 0), (249, 252, 0), (253, 254, 0), (254, 252, 0), (253, 248, 0), (252, 244, 0), (251, 240, 0), (250, 236, 0), (249, 232, 0), (249, 228, 0), (248, 224, 0), (247, 220, 0), (246, 215, 0), (245, 211, 0), (244, 207, 0), (244, 203, 0), (243, 199, 0), (242, 195, 0), (241, 191, 0), (240, 187, 0), (239, 183, 0), (238, 178, 0), (237, 174, 0), (236, 170, 0), (235, 166, 0), (234, 162, 0), (234, 158, 0), (233, 154, 0), (232, 150, 0), (231, 145, 0), (230, 141, 0), (229, 137, 0), (229, 133, 0), (227, 129, 0), (226, 125, 0), (225, 121, 0), (224, 117, 0), (224, 113, 0), (223, 108, 0), (222, 104, 0), (221, 100, 0), (220, 96, 0), (219, 92, 0), (219, 88, 0), (218, 84, 0), (217, 80, 0), (216, 76, 0), (215, 71, 0), (214, 67, 0), (213, 63, 0), (212, 59, 0), (211, 55, 0), (210, 51, 0), (209, 47, 0), (209, 43, 0), (208, 39, 0), (207, 34, 0), (206, 30, 0), (205, 26, 0), (204, 22, 0), (204, 18, 0), (203, 14, 0), (202, 10, 0), (201, 6, 0), (200, 2, 0), (200, 2, 2), (201, 5, 5), (201, 8, 8), (202, 11, 11), (203, 14, 14), (204, 18, 18), (204, 21, 21), (205, 24, 24), (206, 27, 27), (206, 30, 30), (207, 33, 33), (208, 36, 36), (208, 40, 40), (209, 43, 43), (210, 46, 46), (211, 49, 49), (211, 52, 52), (212, 55, 55), (212, 58, 58), (213, 62, 62), (214, 65, 65), (215, 68, 68), (215, 71, 71), (216, 75, 75), (217, 78, 78), (217, 81, 81), (218, 84, 84), (219, 87, 87), (220, 90, 90), (220, 94, 94), (221, 97, 97), (221, 100, 100), (222, 103, 103), (223, 106, 106), (223, 109, 109), (224, 112, 112), (225, 116, 116), (226, 119, 119), (226, 122, 122), (227, 125, 125), (227, 129, 129), (228, 132, 132), (229, 135, 135), (230, 139, 139), (230, 142, 142), (231, 145, 145), (232, 148, 148), (232, 151, 151), (233, 154, 154), (234, 157, 157), (235, 161, 161), (235, 164, 164), (236, 167, 167), (236, 170, 170), (237, 173, 173), (238, 176, 176), (239, 179, 179), (239, 183, 183), (240, 186, 186), (241, 189, 189), (241, 193, 193), (242, 196, 196), (243, 199, 199), (243, 202, 202), (244, 205, 205), (245, 208, 208), (246, 211, 211), (246, 215, 215), (247, 218, 218), (247, 221, 221), (248, 224, 224), (249, 227, 227), (250, 230, 230), (250, 233, 233), (251, 237, 237), (251, 240, 240)) 



2015년 7월 9일 목요일

[작업중] Barrel Distortion이라 불리는 렌즈 왜곡 해결 알고리즘

우선 Barrel Distortion이란 무엇인지 다음의 사진을 보면 명확해진다.


[참고자료]
http://www.tannerhelland.com/4743/simple-algorithm-correcting-lens-distortion/
http://sprg.massey.ac.nz/ivcnz/Proceedings/IVCNZ_73.pdf

2014년 12월 26일 금요일

[번역] 산업용 이미지 센서 포멧과 렌즈 규격

1. 1 인치 비디오 포멧의 의미는 ?

실제 영상 사이즈(active area)는 영상의 대각선 길이가 16mm인 12.8mm x 9.6mm의 영역을 일컬음. 공통 포멧으로 사용되는 1인치(25.40mm)의 수치는 Videcon Tubes의 시대에서 비롯된 것으로 실제 영상 사이즈를 일컫는 것이 아니고 tube의 대각선 길이를 묘사 하는데 사용되어졌다.

2. 2/3 인치 비디오 포멧의 의미는 ?

실제 영상 사이즈(active area)는 영상의 대각선 길이가 11mm인 8.8mm x 6.6mm의 영역을 일컬음. 공통 포멧으로 사용되는 2/3인치 (16.93mm)의 수치는  Videcon Tubes의 시대에서 비롯된 것으로 실제 영상 사이즈를 일컫는 것이 아니고 tube의 대각선 길이를 묘사 하는데 사용되어졌다.

3. 1/2 인치 비디오 포멧의 의미는 ?

실제 영상 사이즈 (active area)는 영상의 대각선 길이가 8mm인 6.4mm x 4.8mm의 영역을 일컬음. 공통 포멧으로 사용되는 1/2인치 (12.70mm)의 수치는 Videcon Tubes의 시대에서 비롯된 것으로 실제 영상 사이즈를 일컫는 것이 아니고 tube의 대각선 길이를 묘사 하는데 사용되어졌다.

4. C-Mount란 무엇인가 ?

C-Mount는 16mm 필름 카메라 뿐만 아니라 CCD/CMOS 디지털 카메라에서 널리 볼 수 있는 카메라/렌즈의 표준 규격이다. C-mount 명세는 그것과 관련된 몇 가지의 치수들을 가지고 있다.

Mounting 나사산 = 1 inch x 32 tpi(Threads per Inch) UN 2A
렌즈 나사산의 길이 = 3.8mm
렌즈의 Flange Focal Distance = 17.52mm
Camera Depth (C-mount 면에서 영상까지의 거리) = 17.52mm

위의 치수들은 어떤 렌즈와 어떤 카메라의 조합도 적절히 영상화되기 위해서 C-Mount 카메라 제조사 뿐만 아니라 모든 C-Mount 렌즈 제조사들에 의해서 따라진다.

5. "C-Mount"와 "CS-Mount" 사이의 차이점은 무엇인가 ?


두 mount 간의 유일한 차이점은 Camera Depth (5mm의 차이)뿐이다.

C-Mount의 Camera Depth (마운트 접촉면에서 상이 맺히는 공간까지의 거리) = 17.52mm
CS-Mount의 Camera Depth = 12.52mm

참고 - 어떤 표준 C-Mount 렌즈도 5mm 확장 튜브를 단순히 적용하면 CS-Mount 카메라에 사용할 수 있다. 그러나, 표준 CS-Mount 렌즈는 C-Mount 카메라에 사용할 수 없다. CS-Mount의 모든 다른 특징들은 C-Mount 특성과 동일하다.

6. F-Mount란 무엇인가 ?

F-Mount는 Nikon사에 의해서 개발되었고 렌즈 제조사에게 뿐만 아니라 수많은 산업용 카메라 회사를 위한 산업 표준이 되었다:

Mounting Interface = Nikon F-Mount Bayonet
Camera Depth (F-Mount 접촉면에서 영상이 맺히는 곳까지의 거리)  = 46.5mm
렌즈의 Flange Focal Distance = 46.5mm

7. T2 나사산 이란 ?

T2 나사산 (미터법 나사산)은 카메라와 렌즈를 결합하는데 일반적으로 사용되는 M42 x 0.75pitch의 나사산을 의미한다.

8. Pentax 나사산 이란 ?

Pentax 나사산 (미터법 나사산)은 카메라와 렌즈를 결합하는데 일반적으로 사용되는 M42 x 1.0 pitch의 나사산을 의미한다.

9. Leica 나사산 이란 ?

Leica 나사산은 나사산의 pitch에 인치 규격을 채용할 뿐만 아니라 나사산의 직경에서 미터법을 채용한 하이브리드 나사산이다:

M39 x 26Gg

주의 - 26Gg pitch는 1mm pitch에 매우 가깝다. 실제 Leica 나사산 (피치가 26Gg 인) 은 정확하게 pitch가 1mm는 아니다.

10. 렌즈의 "Back Focal Distance"와 "Flange Focal Distance"사이의 차이점 ?

렌즈의 Back Focal length 는 렌즈의 맨 마지막 유리 부품 (최외각의 외부와 맞닿는 돌출부)에서 상이 맺히는 곳까지의  거리.

Flange Focal Distance 는 렌즈의 mount 부 (나사산의 초입 면)에서 상이 맺히는 곳 까지의 거리.

11. 가시광 영역에 해당하는 것은 ?

일반적으로 가시광에 해당하는 파장 영역은 사람의 눈이 볼 수 있는 400nm 에서 700nm (파랑에서 빨강 영역)이다.

참고로 - 1 nanometer (nm) = 1 x 10-9meters

12. 일반적인 CCD 센서가 영상을 생성할 수 있는 파장 영역은 ?

어떤 특수한 파장 제한 필터를 적용하지 않은 일반적인 CCD 혹은 CMOS 센서는 가시광에서 근적외선 영역까지의 빛을 영상화 할 수 있다:

400nm 에서 1200nm까지

참고로 - 1 nanometer (nm) = 1 x 10-9meters

13. CCTV는 무엇의 약자인가?

CCTV 는 Closed Circuit Television의 약자이다.

14. Spot 필터는 무엇인가 ?

Schneider 렌즈의 모터로 움직이는 조리게 버전들은 Spot 필터와 같이 공급된다.

Spot 필터가 있는 렌즈를 통해 보면, Spot 필터는 렌즈의 정중앙에 아주 작은 검은 점으로 나타난다.

Spot 필터는 반사체 (파장에 독립적인)의, Neutral Density (고른 밀도), 원판의, graident 필터이다.이것은 optical stop surface (조리개의 날개가 위치하는)에 동일평면상에 위치하도록 유리면에 도포된다. Spot 필터는 즉각적인 광 민감도 적응을 하도록 한다. 외각에 비해 순수하게 어두운 중앙의 Spot 필터를 통과하는 빛은 100% 사라지게 된다. 그래서, 조리개의 날개가 약간이라도 움직이면, 렌즈를 통한 빛의 최종적인 밝기에 아주 지대한 영향을 준다.

모터로 움직이는 렌즈는 spot 필터 없이도 구매 되어 질 수 있지만, 가격의 차이는 없다. 대부분의 모든 고객들이 이것이 무엇인지 이해한다면 spot 필터를 원한다. 용도가 빛이 적은 곳에서 시작하는 곳 일 경우에만 모터로 움직이는 조리개 렌즈에 spot 필터를 원하지 않는 고객들을 보았다.
   

[출처] https://www.schneideroptics.com/info/faq/industrial.htm

2014년 7월 29일 화요일

[번역중] 초분광 카메라 혹은 스펙트로 미터를 위한 분광기 설계

[출처 : http://www.ibsenphotonics.com/technology/spectrometer-design-guide#optics]

소개

이 문서는 diffraction grating 에 기반한 분광기 디자인과 다양한 diode array (리니어 센서) 들을 비교하고 평가하고 디자인하기 위한 공식과 디자인 가이드 라인을 사용하기 쉽고 간단하게 제공합니다.

디자인 과정에 투여되는 입력은 당신이 다루기 원하는 파장 범위와 당신의 스펙트럼에서 얼마나 다양한 구조들을 분석하는지에 따른 광학 분해능등이다.

주의 !

이 안내서를 사용해서 만드는 분광기 디자인은 당신의 디자인 과정의 초입단계에서만 사용되어져야 합니다. 하드웨어적으로 분광기를 구현하고자한다면 미세한 디자인이 가능한 수치적인 시뮬레이션 도구를 항상 사용해야만 합니다. (예를 들자면 geometrical ray tracing).

어떻게 diode array 분광가 작동하나


기본적으로 분광기는 감지부에 입력 슬릿으로 부터의 상을 생성하는 렌즈와 거울들로 구성되는 광학 시스템입니다. 렌즈와 거울 사이에는 서로 다른 각도로 다른 파장들을 분사하는 diffraction grating이 위치합니다. 이것은 입력 슬릿으로부터 들어오는 빛의 서로 다른 파장의 성분들이 감지부 array 센서에 서로 다른 위치에 상을 맺도록 합니다.

출처: http://www.ibsenphotonics.com/wp-content/uploads/Spectrometer-design-guide.pdf

다음의 내용에서 두 개의 일반적인 분광기 구조들을 설명합니다; transmission grating에 기반한 것과 꺽인 형태의 Czerny-Turner 구조입니다. 또한, 그림들은 분광기의 중요한 디자인 변수들을 정의 합니다.

출처 : http://www.ibsenphotonics.com/wp-content/uploads/Spectrometer-design-guide.pdf

최소 파장:
최대 파장:
파장 대역:
파장 해상도
중심 파장

입사각
반사각



2011년 6월 23일 목요일

여러 파일로된 USB2000의 스펙트럼 데이터들을 하나의 파일로 합치는 python 프로그램

NIR 스펙트로미터인 USB2000에서 획득한 스펙트럼 데이터들을(여러개의 파일로 되어 있는) 하나의 파일로 된 매트릭스형태로 합성해 주는 python 스크립트 프로그램이다.

사용방법은 다음과 같다. 우선 리눅스 시스템의 경우 기본적으로 설치되어 있지만, 윈도우즈의 경우 python 2.x 버전의 프로그램을 설치한다. 그리고 USB2000에서 획득한 여러개의 스펙트럼 데이터 파일들을 분류하여 하나의 파일로 만들고 싶은 것들만 하나의 디렉토리로 이동 시키고, 해당 디렉토리에 이 스크립트 파일을 복사하고 실행시키면 해당 디렉토리에 하나의 파일로 합쳐진 매트릭스형태의 스펙트럼 데이터가 생성된다.

 # Usage: copy the script into the directory existing spectrum data and execute it.  
 #!/usr/bin/python  
 import os  
 #import os.path  
 path = "./"  
 dirlist = os.listdir(path)  
 newdirlist = []  
 for fname in dirlist:  
  if os.path.isfile(fname) and fname.find(".Master.Scope") != -1:  
  i = dirlist.index(fname)  
  num = fname.split('.')  
  if num[0].isdigit():  
   newdirlist.append(int(num[0]))  
 newdirlist.sort()  
 #newdirlist.sort(reverse=True)  
 #print newdirlist  
 # the number of samples  
 samples = len(newdirlist)  
 # the number of pixels  
 fname = str(newdirlist[0]) + ".Master.Scope"  
 f = open(fname)  
 lines = f.readlines()  
 f.close()  
 for line in lines:  
  if str(line).find("Number of Pixels in File: ") &gt;= 0:  
  columns = line.split(": ")  
  pixels = int(columns[1])  
  else:  
  if str(line).find("&gt;&gt;&gt;&gt;&gt;Begin Spectral Data&lt;&lt;&lt;&lt;&lt;") &gt;= 0:  
   istart = lines.index(line) + 1  
  else:  
   if str(line).find("&gt;&gt;&gt;&gt;&gt;End Spectral Data&lt;&lt;&lt;&lt;&lt;") &gt;= 0:  
   iend = lines.index(line) - 1  
 print "the # of samples: ", samples  
 print "the # of pixels: ", pixels  
 print "the index of start: ", istart  
 print "the index of end: ", iend  
 signals = [ [ 0 for j in range(samples+1) ] for i in range(pixels) ]  
 for j in range(istart, iend+1, 1):  
  line = lines[j]  
  columns = line.split("\t")  
  #print j, columns[j]  
  signals[j-istart][0] = columns[0].strip();  
 # make directory for merged file  
 if not os.path.isdir("merged"):  
  os.mkdir("merged")  
 for i in range(0, samples, 1):  
  num = newdirlist[i]  
  # for num in newdirlist:  
  # read lines in each file  
  fname = str(num) + ".Master.Scope"  
  f = open(fname)  
  lines = f.readlines()  
  f.close()  
  for j in range(istart, iend+1, 1):  
  line = lines[j]  
  columns = line.split("\t")  
  #print j, columns[j]  
  signals[j-istart][i+1] = columns[1].strip();  
 fname = "merged/USB2000.dat"  
 f = open(fname, "w")  
 for j in range(pixels):  
  for i in range(samples+1):  
  f.write(signals[j][i]+"\t")  
  f.write("\n")  
 f.close()  

2011년 6월 14일 화요일

Fresnel's Equation

출처 : http://hyperphysics.phy-astr.gsu.edu/hbase/phyopt/freseq.html

프리즘 설계를 좀더 정교하게 하기위해선 반사와 투과 되는 빛의 양을 정확히 계산이 필요하다. 반사와 굴절되는 빛의 역학관계는 아주 복잡하지만 간단히 Fresnel's Equation으로 설명된다.

프레넬의 공식이라고 읽는 것 같다. 프레넬의 공식은 경계면에서 electromagnetic 파(빛에만 국한되는 것은 아닌거 같다.)의 반사(reflection)와 투과(transmission)를 설명한다. 이 공식은 입사하는 파의 평면에 평행한 파와 수직인 파의 반사 및 투과의 coefficient를 묘사한다.

dielectric medium (비전기성을 띄는 물질)에 대해서는 익히 들어온 Snell's 법칙이 입사각과 투과각에 대해서만 사용되어질 수 있지만, 프레넬의 공식은 입사각과 투과각에 대해서도 설명하고 있다.






입사 전의 매질의 굴절율을 n1

그리고 입사후의 매질의 굴절율을 n2

입사각을 θi

그리고 투과각을 θt라고 하자.






프레넬의 공식에서 reflection coefficient 는 





transmission coefficient 는

과 같다.
주의 할 것은 이 coefficient들은 아주 적은 값의 분수형태의 정량값이고, 그 부호는 공간의 방향에 선택에 따라 달라진다.
혹시 여러분이 transmission coefficient의 값을 1보다 큰 값으로 지정할 수 도 있지만, 이것은 에너지 보존 법칙에 위배된다.  (예를 들면, 입사 방향의 메질의 굴절율 n1 = 1.5이고 입사된 매질의 굴절율 n2 = 1.0이고 입사각이 30도인 경우를 살펴보라) 그러나 transmission coefficient의 제곱값은 투과된 에너지의 flux per area의 형태(intensity)를 나타낸다. 그리고 투과된 이후의 공간의 굴절율이 입사쪽의 매질의 굴절율보다 작다면 입사하는 빛의 양보다 굴절후의 빛이 적다. 여러분이 반사 및 굴절된 빔의 공간에 대해 고려해 볼때, 전체적인 에너지의 흐름은 물론 굴절및 반사되는 빛의 흐름이 입사하는 빛과 같아야한다. 좀 더 자세하게 이야기 하면, Jenkins와 White의 관련 내용을 보라.
이러한 상황에서의 에너지 보존은 다음과 같은 관계를 보인다.


이것은 평행한 빛과 수직한 빛 모두에 적용될 수 있다.