Fonctionnement
Ce TP doit permettre de comprendre comment fonctionne une chane d'acquisition d'image
numrique. Dans un premier temps, on tudiera le fonctionnement gnral du capteur de lumire, le
CCD (Capteur Charges Dfilantes = Charge Coupled Device). Dans un deuxime temps, on
tudiera la mise en forme des horloges permettant de lire l'image contenue dans le CCD. Cette tude
sera illustre par l'analyse du listing du logiciel de pilotage. Dans un troisime temps, on tudiera
une partie des diffrents signaux avec un oscilloscope.
Mise sous tension : bouton +15/-15 Volt. Ne pas allumer le refroidissement Peltier.
1.1.1 Le photosite
La surface de silicium est divise en une matrice de photosites. Sensible la lumire, le photosite
peut tre grossirement assimil un condensateur qui absorbe l'nergie des photons incidents en
gnrant des lectrons (les charges). Les lectrons sont pigs dans le puits de potentiel du
photosite.
1/14
C'est l'enchanement des oprations lmentaires des horloges V et H qui va conditionner l'ordre de
sortie des charges. Dans l'exemple ci-dessus, le listing suivant (langage C) permet de rcuprer une
image dont chaque pixel sera reprsente par un photosite de la matrice CCD :
/* --- lecture et digitalisation simple (binning 1x1) ---*/
int kl,kc;
int nl=4,nc=6;
unsigned short p;
p=(unsigned short*)calloc(nl*nc,sizeof(unsigned short));
for (kl=1;kl<=nl;kl++) {
1_transfert_vertical;
for (kc=1;kc<=nc;kc++) {
1_transfert_horizontal;
p[nl*kc+kl]=numrisation;
}
}
La fonction calloc permet d'allouer de la place mmoire pour y stocker l'image.
Sous chaque photosite, le puits de potentiel se compose de 4 parties couples deux deux dans la
technologie du transfert deux phases relles. Le KAF400 utilise le principe du transfert des
charges deux phases.
2/14
A gauche en haut : reprsentation schmatique de la coupe d'une ligne de photosites CCD. Les
horloges 1 et 2 sont des tensions appliquer aux lectrodes. A gauche en bas, reprsentation des
niveaux de potentiels associs aux photosites. Au cours des trois tapes t1, t2 et t3, les charges Q1
Q5 sont dplaces vers la droite. A droite, reprsentation schmatique des niveaux des horloges 1
et 2 correspondant aux trois tapes. Ce schma s'appelle chronogramme. La dnomination de ces
horloges devient V1 et V2 lorsqu'il s'agit du transfert vertical (H1 et H2 lorsqu'il s'agit du
transfert horizontal)
1.1.3. La matrice
A partir document ci-dessous, reprer les caractristiques (nombres de pixels) et les diffrentes
zones de la matrice CCD (pixels cachs la lumire, etc.) pour le Kaf400.
3/14
1.1.5. Le binning
En reprenant la matrice dcrite au paragraphe 1.1.2., le listing a t modifi pour regrouper les
lectrons de plusieurs photosites pour ne faire qu'un seul pixel.
/* --- lecture et digitalisation en binning 2x2 ---*/
int kl,kc;
int nl=2,nc=3;
unsigned short p;
p=(unsigned short*)calloc(nl*nc,sizeof(unsigned short));
for (kl=1;kl<=nl;kl++) {
1_transfert_vertical;
1_transfert_vertical;
for (kc=1;kc<=nc;kc++) {
1_transfert_horizontal;
1_transfert_horizontal;
p[nl*kc+kl]=numrisation;
}
}
Identifier quels sont les photosites qui sont ainsi regroups. Ecrire la matrice dans laquelle ont
notera les lettres rassembles dans chaque pixel.
Faire l'acquisition d'images en binning 4x4, 2x2 et lx1. Faire le bilan des ce que l'on gagne et de ce
que l'on perd (temps de lecture, dfinition, temps de pose, stockage de l'image, etc.) lors d'une
acquisition en binning 4x4 compar une acquisition en binning lx1.
2. Le chronogramme
Le chronogramme est l'enchanement des variations des tensions appliques aux bornes du capteur
CCD. Il s'agit de tensions en crneaux (un tat haut et un tat bas). Ces signaux permettent de
dcaler les charges dans les cellules du capteur CCD afin de les faire sortir par une broche de sortie.
Ci-dessous, le chronogramme gnral de lecture de la matrice CCD (document Kodak) :
Le tableau ci-dessous, indique les dures minimales respecter pour assurer un bon transfert des
lectrons:
5/14
Les deux chronogrammes ci-dessus, montrent les dtails du chronogramme respecter pour une
lecture en binning 1x1. Vout correspond la tension en sortie du composant CCD.
2.2. Vidage
Le vidage consiste en l'vacuation rapide des charges de la matrice CCD, sans numrisation. Ainsi,
on dcharge la matrice CCD et une nouvelle image peut s'y former. Expliquer la fonction
fast_vidage du listing.
2.3. Lecture
La lecture consiste faire sortie les pixels aprs le temps d'intgration (temps de pose). A la sortie
de chaque pixel, on va numriser le signal de faon transformer les charges lectriques en units
convertisseur. Expliquer la fonction read_win du listing et dessiner la forme attendue du signal
vido d'un pixel la sortie du CCD en prcisant chacune des tapes. Rpondre aux questions
suivantes
Expliquer pourquoi et comment un pixel est caractris par trois paliers : reset, rfrence,
vido.
6/14
3.1. Analyse de V1 V2
Statuts de loscilloscope
VI sur l'entre 1,
V2 sur l'entre 2,
En binning 1x1, temps de pose 10 secondes, reprer la squence de vidage et la squence de lecture.
Idem en binning 4x4 puis en binning 2x2. Noter la dure de chaque palier dans chacune des
squences. En dduire le temps mis par une opration libcam_out dans le listing.
3.2. Analyse de H1 et H2
Analyser, en binning 1x1, les diffrents signaux suivants (en distinguant les squences de vidage et
de lecture). On remarquera que H2 est toujours en opposition avec H1.
Statuts de loscilloscope
H1 sur l'entre 1,
R sur l'entre 2,
Statuts de loscilloscope
V2 sur l'entre 1,
H1 surl'entre2,
7/14
R sur l'entre 1,
CL sur l'entre 2,
8/14
/*
* tp.c
*
* Fichier pour travaux pratiques de maitrise
* Universite Paul Sabatier
*
* --- rappel des bits de donnes du port parallele pour Audine
*
ordre : 87654321
*
bit 1 : horloge V1
*
bit 2 : horloge V2
*
bit 3 : horloge H1
*
bit 4 : horloge R (reset)
*
bit 5 : horloge CL (clamp)
*
bit 6 : horloge Start Convert (CAN)
*
bit 7 : horloge Select Byte (CAN)
*
bit 8 : horloge Select Nibble
*
* N.B. Si le bit est 0 alors la tension est au niveau haut.
*
Si le bit est 1 alors la tension est au niveau bas.
*/
#include "sysexp.h"
#if defined(OS_WIN)
#include <windows.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "camera.h"
#include "libcam.h"
#include "camtcl.h"
#include "util.h"
/* declaration des fonctions locales ce fichier .c */
void
void
void
void
void
void
void
void
void
/*
/*
/*
/*
/*
==================================================================
==================================================================
=== Fonctions appeles par l'interface pour piloter la camera ===
==================================================================
==================================================================
*/
*/
*/
*/
*/
/*
* cmdCamAcqNormal()
*
* La structure cam est definie dans le fichier libcam.h
* au niveau de la definition #define COMMON_CAMSTRUCT
*
* Les fonction commenant par libcam sont dfinies dans
* le fichier util.c
*
* La fonction atoi transforme le contenu d'une chaine de carateres
* de type char* en un nombre entier de int.
*
* La fonction sprintf a le meme effet que fprintf mais elle envoie
* la chaine de caracteres vers un pointeur char*.
*
*/
int cmdCamAcqNormal(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
{
struct camprop *cam;
9/14
char s[256];
int i;
int nb_vidages = 4;
int naxis1, naxis2,t;
unsigned short *p;
float *pp;
cam = (struct camprop*)clientData;
/* =============================================== */
/* === Etape de rincage de la matrice CCD
=== */
/* =============================================== */
/* Bloquage des interruptions */
if (cam->interrupt==1) { libcam_bloquer();}
/* vidage de la matrice */
for (i=0;i<nb_vidages;i++) fast_vidage(cam);
/* Debloquage des interruptions */
if (cam->interrupt==1) { libcam_debloquer();}
/* Remise a l'heure de l'horloge du PC */
update_clock();
/* =============================================== */
/* === Integration de l'image (attente)
=== */
/* =============================================== */
/* Delais du temps de pose (en millisecondes) */
libcam_sleep((int)(1000*cam->exptime));
/* =============================================== */
/* === Etape de lecture de la matrice CCD
=== */
/* =============================================== */
/* Bloquage des interruptions */
if (cam->interrupt==1) { libcam_bloquer();}
/* Parametres de dimensions pour allouer le pointeur image */
naxis1 = cam->nb_photox/cam->binx;
naxis2 = cam->nb_photoy/cam->biny;
/* Allocation memoire du pointeur image */
p = (unsigned short*)calloc(naxis1*naxis2,sizeof(unsigned short));
/* Lecture et numrisation de l'image vers le pointeur p */
read_win(cam,p);
/* Debloquage des interruptions */
if (cam->interrupt==1) { libcam_debloquer();}
/* Remise a l'heure de l'horloge du PC */
update_clock();
/* =============================================== */
/* === Copie des valeurs des pixels a partir
=== */
/* === du pointeur local vers le pointeur Tcl === */
/* =============================================== */
/* Allocation memoire du buffer image (pour l'interface) */
sprintf(s,"buf%d format %d %d",cam->bufno,naxis1,naxis2);
Tcl_Eval(interp,s);
/* Recupere l'adresse du pointeur buffer */
sprintf(s,"buf%d pointer",cam->bufno);
Tcl_Eval(interp,s);
pp = (float*)atoi(interp->result);
/* Transfere les donnes du pointeur *p vers le pointeur *pp */
t = naxis1 * naxis2;
while (--t>=0) {
*(pp+t) = (float)*((unsigned short*)(p+t));
}
/* Liberation du pointeur local *p */
free(p);
/* =============================================== */
/* === Complete le buffer Tcl
=== */
/* =============================================== */
/* Assigne le type de donnes qui seront enregistres sur le disque */
sprintf(s,"buf%d bitpix ushort",cam->bufno);
Tcl_Eval(interp,s);
/* Mots cls pour l'entete du fichier image */
10/14
================================================================
================================================================
===
Fonctions de base pour le pilotage de la camera
===
================================================================
================================================================
Ces fonctions sont tres specifiques a chaque camera.
================================================================
*/
*/
*/
*/
*/
*/
*/
/*
fast_vidage(struct camprop *cam) -Vidage rapide de la matrice. Le decalage des lignes s'effectue
ici par groupe de 32, mais est le seul parametre a regler ici.
*/
void fast_vidage(struct camprop *cam) {
int i, j;
int imax, jmax, decaligne;
#ifdef __linux__
int toto;
#endif
/* Nombre de lignes decalees a chaque iteration.*/
decaligne = 32;
/* Calcul des constantes de vidage de la matrice. */
imax =
cam->nb_photox + cam->nb_deadbeginphotox + cam->nb_deadendphotox ;
jmax = ( cam->nb_photoy + cam->nb_deadbeginphotoy + cam->nb_deadendphotoy ) /
decaligne + decaligne;
/* Demande d'acces aux ports pour linux */
#ifdef __linux__
toto=iopl(3);
if(toto!=0) {
fprintf(stderr,"Impossible d'acceder au port parallele.\n");
exit(1);
}
#endif
for(j=0;j<jmax;j++) {
/* Decalage des lignes. */
for(i=0;i<decaligne;i++) zi_zh(cam);
/* Lecture du registre horizontal. */
/* sans reset */
for(i=0;i<imax;i++) read_pel_fast2(cam);
}
}
/*
zi_zh(struct camprop *cam) -Decalage vertical de toutes les lignes d'un cran vers le bas.
11/14
/*
/*
/*
/*
/*
11111011
11111010
11111001
11111010
11111011
*/
*/
*/
*/
*/
/*
read_pel_fast(struct camprop *cam) -Lecture rapide d'un pixel : decalage du registre horizontal
avec Reset, mais sans lecture du CAN,
*/
void read_pel_fast(struct camprop *cam)
{
unsigned short port = cam->port;
libcam_out(port,0xF7); /* 11110111 */
libcam_out(port,0xFF); /* 11111111 */
libcam_out(port,0xFB); /* 11111011 */
}
/*
read_pel_fast2(struct camprop *cam) -Lecture rapide d'un pixel : decalage du registre horizontal
sans Reset, mais sans lecture du CAN,
*/
void read_pel_fast2(struct camprop *cam)
{
unsigned short port = cam->port;
libcam_out(port,0xFF); /* 11111111 */
libcam_out(port,0xFB); /* 11111011 */
}
/*
fast_line_() -Lecture rapide du registre horizontal, avec la fonction read_pel_fast.
*/
void fast_line(struct camprop *cam)
{
int i, imax;
imax = cam->nb_photox + cam->nb_deadbeginphotox + cam->nb_deadendphotox ;
for (i=0;i<imax;i++) read_pel_fast(cam);
}
/*
fast_line2() -Lecture rapide du registre horizontal, avec la fonction read_pel_fast2.
*/
void fast_line2(struct camprop *cam)
{
int i, imax;
imax = cam->nb_photox + cam->nb_deadbeginphotox + cam->nb_deadendphotox ;
for (i=0;i<imax;i++) read_pel_fast2(cam);
}
/*
read_win(struct camprop *cam,short *buf) -Lecture normale du CCD, avec un fenetrage possible.
*/
void read_win(struct camprop *cam,unsigned short *buf)
{
int i,j;
int k,l;
int imax,jmax;
int cx1,cx2,cy1;
12/14
13/14
x = ((a1>>4)+a2+(a3<<4)+(a4<<8))^0x8888;
if (x>32767) x=32767;
/* Stockage dans un buffer dans la meme page mem */
buffer[j] = (unsigned short)x;
}
/* On retire cx2 pixels la fin */
for (j=0;j<cx2;j++) read_pel_fast(cam);
/* On transfere le tableau vers la matrice image */
if (i!=0) {
p0[(i-1)*imax]=buffer[0];
}
for(j=1;j<imax;j++) {
p0[(i+1)*imax-j]=buffer[j];
}
}
}
14/14