By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,996 Members | 1,498 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,996 IT Pros & Developers. It's quick & easy.

Video capture works with 1 and 2 web cam but not with 3

P: n/a
Hello,


I made a program to capture photos from 3 web cams (with video capture).

With one or two cams, the program works perfectly.

With 3 cams, my program doesn't work.

The third window still blank (white).

This is my code (in attachement). Do you have the time to check it ?

It will be very kind of you.

Thank you in advance.
David
Belgium

Expand|Select|Wrap|Line Numbers
  1. cam.txt
  2.  
  3. #coding:latin1
  4.  
  5. """
  6. name: Camera Manager
  7. version: 2.0.1
  8. author: nano corp.
  9.  
  10. """
  11.  
  12. from tkMessageBox import askyesno
  13. from Tkinter import Tk,LabelFrame,Button,Entry,Label,Spinbox,Frame,StringVar,\
  14.      Radiobutton,Checkbutton,BooleanVar,Text,END
  15. from time import time,sleep,gmtime
  16. from Image import fromstring
  17. import Image
  18. from vidcap import new_Dev
  19. import pymedia.video.vcodec as vcodec
  20. import os,sys, user
  21.  
  22. #Réglage du nombre limite de récursion
  23. sys.setrecursionlimit(1024**2)
  24.  
  25.  
  26. ### Définition des constantes
  27. # Quelques valeurs globales #
  28. larg_chk = 16
  29. larg_btn = 16
  30. larg_msg = 33
  31.  
  32. # Quelques paramètres
  33. default_delay = 240   #La valeur par défaut du délai (en secondes) :240
  34. dec_delay = 10  #La valeur unitaire du délai :10
  35. default_acq = 1080    #Le nombre d'acquisition par défaut :1080
  36. default_duree = 60    #La durée par defaut de la vidéo (en secondes) :60
  37.  
  38.  
  39.  
  40. ### Défintion des fonctions ###
  41. def convert(tps=0):
  42.     """converti un nombre donné de secondes
  43. en jours,heures,minutes,secondes"""
  44.     sec = tps%60
  45.     min = (tps/60)%60
  46.     heu = (tps/3600)
  47.     day = (heu/24)
  48.     heu = heu%24
  49.     return (day,heu,min,sec)
  50.  
  51.  
  52.  
  53. ### Défintion des classes ###
  54. class Timer:
  55.     """ Classe servant de chronomètre"""
  56.     def __init__(self,tps=None):
  57.         if tps==None:
  58.             self.restant = 3*24*3600 #3 jours par défaut.
  59.         self.init = tps
  60.     def start(self,tps):
  61.         """Initialise le chronomètre"""
  62.         self.total = tps
  63.         self.restant = tps
  64.         self.conte = 0
  65.         self.init = time()
  66.     def get(self):
  67.         """renvoie le temps restant sous forme
  68. jours,heures,minutes,secondes"""
  69.         self.tps = int(self.restant-(time()-self.init))
  70.         return convert(self.tps)
  71.  
  72.     def get_duree(self):
  73.         """renvoie la durée écoulé"""
  74.         return time()-self.init
  75.  
  76.  
  77. def BuildVideo ( images,output_filename,size,time=60 ):
  78.     '''Construit une vidéo à partir de la liste d'images.
  79.        images          : liste des noms de fichiers des images
  80.        output_filename : nom de la video (attention à l'extension)
  81.        size            : (largeur,hauteur) en pixels de la vidéo générée
  82.        Les paramètres du codec sont ceux trouvés dans les tutoriels de pymedia.
  83.        '''
  84.     nb_images = 1
  85.     if len(images)>1:
  86.         nb_images = len(images)
  87.     if nb_images>=20:
  88.         frame_rate_base = 1567641600/nb_images
  89.         frame_rate = frame_rate_base*nb_images/time
  90.         rate = frame_rate/frame_rate_base
  91.         params = {
  92.                   'type'            : 0,
  93.                   'gop_size'        : 12,
  94.                   # frame rate = frame_rate/frame_rate_base : ici déterminer par la duree et le nb d'images
  95.                   # attention : tous les frames rate ne sont pas supportés
  96.                   'frame_rate'      : frame_rate_base*nb_images/time,
  97.                   'frame_rate_base' : frame_rate_base,
  98.                   'max_b_frames'    : 0,
  99.                   'height'          : size[1],
  100.                   'width'           : size[0],
  101.                   'deinterlace'     : 0,
  102.                   'bitrate'         : 2700000,
  103.                   'id'              : vcodec.getCodecID( 'mpeg1video' ) }
  104.  
  105.         #Lorsqu'il y a peu d'images cela pose quelques problèmes
  106.     else:
  107.         rate = 1
  108.         params = {
  109.                   # frame rate = frame_rate/frame_rate_base : ici = 1 im/sec
  110.                   # attention : tous les frame rate ne sont pas supportés
  111.                   'frame_rate'      : 1,
  112.                   'frame_rate_base' : 1,
  113.                   'max_b_frames'    : 0,
  114.                   'height'          : size[1],
  115.                   'width'           : size[0],
  116.                   'deinterlace'     : 0,
  117.                   'bitrate'         : 2700000,
  118.                   'id'              : vcodec.getCodecID( 'mpeg1video' ) }
  119.  
  120.         tmp = [images[0]]
  121.         for i in range(time):
  122.             pos = i*nb_images/time
  123.             tmp.append(images[pos])
  124.         images = tmp
  125.  
  126.     encoder = vcodec.Encoder( params ) # créé une instance d'encodeur
  127.     output = open( output_filename,'wb' ) # créé le fichier de sortie
  128.  
  129.     for i,im in enumerate(images) :
  130.         # recupère l'image sous forme d'une string raw
  131.         bitmap    = Image.open( im ).resize( size ).tostring()
  132.         # en fait une frame rgb
  133.         frame_rgb = vcodec.VFrame( vcodec.formats.PIX_FMT_RGB24,size,
  134.                                    ( bitmap,None,None ),rate=rate,
  135.                                    frame_number=i,pts=i,resync=True)
  136.         f = frame_rgb
  137.         # la convertit en frame yuv (l'encodeur n'accepte pas directement du rgb)
  138.         frame_yuv = frame_rgb.convert( vcodec.formats.PIX_FMT_YUV420P )
  139.         # encode la frame
  140.         encoded   = encoder.encode( frame_yuv )
  141.         # ajoute la frame encodée au fichier
  142.         output.write( encoded.data )
  143.         # laisse 1
  144.         sleep(0.001)
  145.     # ferme le fichier de sortie
  146.     output.close()
  147.  
  148.  
  149. ### nouvelle classe! ###
  150.  
  151. class Progress(Frame):
  152.     """Barre de progression"""
  153.     def __init__(self,master=None,value=0,width=32,bg='gray'):
  154.         Frame.__init__(self,master,width=width,relief='sunken',bd=2)
  155.         self.larg =width
  156.         width = int(value/width)
  157.         #Le label qui représentera la partie effectuée
  158.         self.lbl = Label(self,bg=bg)
  159.         self.lbl.pack(side='left')
  160.         #Le label qui représentera le reste
  161.         self.rst = Label(self)
  162.         self.rst.pack(side='right')
  163.         self.set(value)
  164.     def set(self,value=0):
  165.         """définit la nouvelle valeur de la barre de progression"""
  166.         width = ((value*self.larg)/100.0)%self.larg
  167.         width = int(width)
  168.         rest = int(round(self.larg-width-1))
  169.         txt1 = ''
  170.         txt2 = ''
  171.         if value>=50:
  172.             txt1 = str(value)+'%'
  173.         else:
  174.             txt2 = str(value)+'%'
  175.         self.lbl.configure(text=txt1,width=width)
  176.         self.rst.configure(text=txt2,width=rest)
  177.         if value == 100:
  178.             self.lbl.configure(width=self.larg)
  179.             self.rst.pack_forget()
  180.         else:
  181.             self.rst.pack(side='right')
  182.  
  183.  
  184. ### Panneau Experiment ###
  185. class panneau1(LabelFrame):
  186.     """ Eléments à accès externe
  187. self.txt_msg:pour le configure la premier zone de message
  188.     self.txt_msg.configure(text=nouveau_message)
  189.  
  190. self.sel_delay:pour la valeur de delay
  191.     self.sel_delay.get() pour récupérer la valeur (puis
  192.     convertir sous forme d'entier): int(val)
  193.  
  194. self.sel_acq:pour la valeur de acq
  195.     self.sel_acq.get() pour récupérer la valeur (puis
  196.     convertir sour forme d'entier): int(val)
  197.  
  198.  
  199. self.txt_total: pour afficher le temps total
  200.     self.txt_total.configure(text=nouveau_temps)
  201.  
  202. self.chk_close: pour la valeur de la case "Close at end"
  203.     self.chk_close.get() pour récupérer le choix de l'utilisateur
  204. """
  205.     def __init__(self,parent=None,func=None):
  206.         LabelFrame.__init__(self,parent,text='Experiment ',bd=4,padx=5,pady=5,
  207.                             width=larg_msg,relief='sunken')
  208.         frm = Frame(self)
  209.         frm.grid(row=1,column=1)
  210.         ## Les labels
  211.         #Le label qui affiche les messages en dessous de Experiment
  212.         tps = gmtime()
  213.         txt_msg = "L.allemnand_FC10_"+str(tps[2]).rjust(2,'0')+"_"+str(tps[1]).rjust(2,'0')+\
  214.                   "_"+str(tps[0])+"_e2"
  215.         self.msg_var = StringVar(self)
  216.         self.msg_var.set(txt_msg)
  217.         frm_txt = LabelFrame(self,text="Répertoire de sauvegarde: ",relief="flat")
  218.         self.txt_msg = Entry(frm_txt,width=larg_msg,textvariable=self.msg_var,
  219.                              relief='sunken')
  220.         lbl_delay = Label(frm,text='Délay(s)',anchor='nw')
  221.         lbl_acq = Label(frm,text='# Acquisition.',anchor='nw')
  222.         lbl_res = Label(frm,text='Résolution',anchor='nw')
  223.         lbl_duree = Label(frm,text='Durée vidéo (s)',anchor='nw')
  224.         lbl_total = Label(frm,text='Total',anchor='nw')
  225.  
  226.         ## Les commandes
  227.         #Le sélecteur de delay
  228.         self.sel_delay = Spinbox(frm,from_=dec_delay,to=302400,width=larg_chk,state="readonly",
  229.                                  bd=2,increment=dec_delay,repeatinterval=20)
  230.         self.var_delay = StringVar(self.sel_delay)
  231.         self.sel_delay.configure(textvariable=self.var_delay)
  232.         self.sel_delay.bind("<KeyRelease>",self.change)
  233.         #Veuillez excuser la méthode un peu violente
  234.         for i in range(0,default_delay,dec_delay):
  235.             self.sel_delay.invoke("buttonup")
  236.         #Le sélecteur de acq.
  237.         self.sel_acq = Spinbox(frm,from_=1,to=1000000,width=larg_chk,state="readonly",
  238.                                bd=2,repeatinterval=10)
  239.         self.var_acq = StringVar(self.sel_acq)
  240.         self.sel_acq.configure(textvariable=self.var_acq)
  241.         self.sel_acq.bind("<KeyRelease>",self.change)
  242.         #Veuillez excuser la méthode un peu violente
  243.         for i in range(default_acq):
  244.             self.sel_acq.invoke("buttonup")
  245.         #Le sélecteur de résolution
  246.         res = (#Résolutions pour une version future de Pymedia (trop petite taille).
  247.                #"128 x 96 (phone)","176 x 144 (phone)",
  248.                "320 x 200 (mobile)","320 x 240 (ipod)","352 x 288 (mobile)",
  249.                "368 x 208 (PSP)","400 x 300 (mobile)","480 x 360 (mobile)","512 x 384 (PC)","640 x 400 (PC)",
  250.                "640 x 480 (PC)","800 x 600 (PC)","1024 x 768 (PC)","1152 x 864 (PC)",)
  251.                #Résolutions pour une version ultérieure de Pymedia (trop grande taille)
  252.                #"1280 x 720 (HD)","1280 x 768 (HD)","1280 x 960 (HD)","1280 x 1024 (HD)","1600 x 900 (VHD)",
  253.                #"1600 x 1024 (VHD)","1600 x 1200 (VHD)","1920 x 1080 (VHD)","1920 x 1200 (VHD)","1920 x 1440 (VHD)",
  254.                #"2048 x 1536 (VHD)")
  255.         self.sel_res = Spinbox(frm,values=res,width=larg_chk,bd=2,state="readonly")
  256.         self.var_res = StringVar(self.sel_res)
  257.         self.sel_res.configure(textvariable=self.var_res)
  258.         for i in range(10):
  259.             self.sel_res.invoke("buttonup")
  260.         #Le sélecteur de la durée
  261.         self.sel_duree = Spinbox(frm,width=larg_chk,bd=2,state="readonly",
  262.                                  from_=10,to=3600*24,increment=10)
  263.         self.var_duree = StringVar(self.sel_duree)
  264.         self.sel_duree.configure(textvariable=self.var_duree)
  265.         #Veuillez excuser la méthode un peu violente
  266.         for i in range(0,default_duree,10):
  267.             self.sel_duree.invoke("buttonup")           
  268.  
  269.         #Le label qui affiche le temps total
  270.         self.txt_total =Label(frm,text='3 jours 00:00:00',width=18,relief='sunken')
  271.         #La case à cocher close_at_end
  272.         self.bol_close = BooleanVar()
  273.         self.bol_close.set(False)             
  274.         self.chk_close = Checkbutton(frm,text="Fermer à la fin",variable=self.bol_close)
  275.         #Le boutton exit
  276.         #C'est à vous de voir comment vous allez gérer la sortie!
  277.         #le paramètre command devra être remplacé par une de vos méthodes
  278.         self.btn_exit = Button(frm,text='Quitter',command=func,
  279.                                width=larg_btn)
  280.  
  281.         ## Affichage des widgets
  282.         frm_txt.grid(row=0,column=1)
  283.         self.txt_msg.pack()
  284.         lbl_delay.grid(row=1,column=1,sticky='w')
  285.         lbl_acq.grid(row=2,column=1,sticky='w')
  286.         self.sel_delay.grid(row=1,column=2,sticky='e')
  287.         self.sel_acq.grid(row=2,column=2,sticky='e')
  288.         lbl_res.grid(row=3,column=1,sticky='w')
  289.         self.sel_res.grid(row=3,column=2,sticky='e')
  290.         lbl_duree.grid(row=4,column=1,sticky='w')
  291.         self.sel_duree.grid(row=4,column=2,sticky='e')
  292.         lbl_total.grid(row=5,column=1,sticky='w')
  293.         self.txt_total.grid(row=5,column=2,sticky='e')
  294.         self.chk_close.grid(row=6,column=1,sticky='w')
  295.         self.btn_exit.grid(row=6,column=2,sticky='e')
  296.         self.sel_delay.configure(command=self.change)
  297.         self.sel_acq.configure(command=self.change)
  298.         self.change()
  299.  
  300.     def change(self,event=None):
  301.         """Met à jour le temps le nécessaire
  302. en fonction du nombre de photos et du délai
  303. unitaire des photos"""
  304.         delay = int(self.sel_delay.get())
  305.         acq = int(self.sel_acq.get())
  306.         self.tps = delay*acq
  307.         self.sel_acq.max = 378432000/delay
  308.         tps = convert(self.tps)
  309.         txt = str(tps[0])+' jours '+str(tps[1]).rjust(2,'0')+':'+\
  310.               str(tps[2]).rjust(2,'0')+':'+str(tps[3]).rjust(2,'0')
  311.         self.txt_total.configure(text=txt)
  312.  
  313.  
  314.  
  315.  
  316. ### Panneau Acquisition ###
  317. class panneau2(LabelFrame):
  318.     """Eléments externes
  319. self.cpt1: La première barre de progression
  320.     self.cpt1.set(valeur) pour changer la valeur du compteur
  321.  
  322. self.txt_acq: pour changer le rapport '331/1030'
  323.     self.txt_acq.configure(text=nouvelle_valeur)
  324.  
  325. self.cpt2: La deuxième barre de progression
  326.     self.cpt2.set(valeur) pour changer la valeur du compte
  327.  
  328. self.txt_time: Pour changer le texte de temps
  329.     self.txt_time.configure(text=nouveau_temps)
  330. """
  331.     def __init__(self,parent=None,rec=None,stop=None,cancel=None):
  332.         LabelFrame.__init__(self,master=parent,text='Acquisition',bd=4,relief='sunken')
  333.         frm = Frame(self)
  334.         # La bare de progession n°1
  335.         self.cpt1 = Progress(frm,width=17,bg="gray70")
  336.         # Le label qui afffiche le rapport de acq
  337.         self.txt_acq = Label(frm,text='0/0',relief='sunken',bd=2,
  338.                              width=16)
  339.         #La barre de progression n°2
  340.         self.cpt2 = Progress(self,width=34,bg="gray45")
  341.         #La barre de progression n°3
  342.         self.cpt3 = Progress(self,width=34,bg="gray")
  343.         #Le label qui affiche la durée
  344.         self.txt_time = Label(self,text='0 jours 00:00:00',width=19,bd=2,
  345.                               relief='sunken',font = "{MS Sans Serif} 14")
  346.         self.txt_time.grid(row=3,sticky='w')
  347.         frm1 = Frame(self)
  348.         #Le boutton d'enregistrement
  349.         #le paramètre command devra être remplacé
  350.         self.btn_rec = Button(frm1,text='REC',bg='red',width=larg_btn,
  351.                               activebackground='red',command=rec)
  352.         #Le bouton d'arrêt
  353.         #le paramètre command devra être remplacé
  354.         self.btn_stop = Button(frm1,text='STOP',width=larg_btn,command=stop)
  355.  
  356.         #Le bouton d'annulation
  357.         self.btn_cancel = Button(self,text='CANCEL',width=larg_btn*2+2,command=cancel)
  358.  
  359.         ## Affichage des widgets
  360.         self.cpt1.grid(row=1,column=1,sticky='w')
  361.         self.txt_acq.grid(row=1,column=2,sticky='e')
  362.         self.cpt2.grid(row=2,sticky='w')
  363.         self.cpt3.grid(row=4,sticky='w')
  364.         frm.grid(row=1,sticky='w')
  365.         self.btn_rec.grid(row=1,column=1,sticky='w')
  366.         self.btn_stop.grid(row=1,column=2,sticky='e')
  367.         self.btn_cancel.grid(row=6,sticky='w')
  368.         frm1.grid(row=5)
  369.  
  370.  
  371. ### classe Manager ###        
  372. class projet(Tk):
  373.     """ Fenêtre principale
  374. devnum: l'indice de la caméra à utiliser 0..n
  375.  
  376. Eléments externes:
  377. self.time: le timer il prend un argument facultatif,le temps de décompte
  378. exprimé en secondes
  379. self.pan_exp: le panneau Experiment
  380. self.pan_acq: le panneau d'Acquisition
  381. """
  382.     nb_instance = [0]
  383.     def __init__(self,devnum=0):
  384.         Tk.__init__(self)
  385.         self.title("Gestionnaire Cam. "+str(devnum))
  386.         self .resizable(False,False)
  387.         self.wm_protocol("WM_DELETE_WINDOW",self.term)
  388.         self.iconbitmap("my_icon.ico")
  389.         self.numero = devnum
  390.         #Le panneau Experiment
  391.         self.pan_exp = panneau1(self,self.term)
  392.         #Le panneau Acquisition
  393.         self.pan_acq = panneau2(self,self.start_rec,self.stop_rec,self.abort_rec)
  394.         ## Affichage des widgets
  395.         self.pan_exp.pack()
  396.         self.pan_acq.pack()
  397.         txt = """
  398. http://www.lib.ac.be.polytech/USA\t
  399. copyright 2010\t\t\t
  400. """
  401.         Label(self,text=txt).pack()
  402.         self.timer = Timer()
  403.         self.rec = False
  404.         self.alive = True
  405.         self.started_rec = False
  406.         self.nb_instance[0] +=1
  407.         #Création de la Caméra
  408.         try:
  409.             self.cam = new_Dev(self.numero,1)
  410.             #Initialisation du visualisateur
  411.             self.getImage()
  412.         except:
  413.             #IL n'y a pas de cam avec cet indice disponible
  414.             #Arrêt du programme!
  415.             #self.term()
  416.             pass
  417.  
  418.     def open_rep(self):
  419.         """ ouvre le dossier contenant les enregistrement. """
  420.         try:
  421.             me = self.rep
  422.             cmd = "start explorer "+self.rep
  423.             os.system(cmd)
  424.         except:
  425.             pass
  426.  
  427.     def getImage(self):
  428.         """Renvoie l'image contenue dans la mémoire tempon
  429. de a caméram"""
  430.         if self.alive:
  431.             buf,w,h = self.cam.getbuffer()
  432.             return fromstring('RGB',(w,h),buf,'raw','BGR',0,-1)
  433.  
  434.  
  435.     def BuildVideo (self,images,output_filename,size,time=60 ):
  436.         '''Construit une vidéo à partir de la liste d'images.
  437.            images          : liste des noms de fichiers des images
  438.            output_filename : nom de la video (attention à l'extension)
  439.            size            : (largeur,hauteur) en pixels de la vidéo générée
  440.            Les paramètres du codec sont ceux trouvés dans les tutoriels de pymedia.
  441.            '''
  442.         nb_images = 1
  443.         if len(images)>1:
  444.             nb_images = len(images)
  445.         if nb_images>=20:
  446.             frame_rate_base = 1567641600/nb_images
  447.             frame_rate = frame_rate_base*nb_images/time
  448.             rate = frame_rate/frame_rate_base
  449.             params = {
  450.                       'type'            : 0,
  451.                       'gop_size'        : 12,
  452.                       # frame rate = frame_rate/frame_rate_base : ici déterminer par la duree et le nb d'images
  453.                       # attention : tous les frames rate ne sont pas supportés
  454.                       'frame_rate'      : frame_rate_base*nb_images/time,
  455.                       'frame_rate_base' : frame_rate_base,
  456.                       'max_b_frames'    : 0,
  457.                       'height'          : size[1],
  458.                       'width'           : size[0],
  459.                       'deinterlace'     : 0,
  460.                       'bitrate'         : 2700000,
  461.                       'id'              : vcodec.getCodecID( 'mpeg1video' ) }
  462.  
  463.             #Lorsqu'il y a peu d'images cela pose quelques problèmes
  464.         else:
  465.             rate = 1
  466.             params = {
  467.                       # frame rate = frame_rate/frame_rate_base : ici = 1 im/sec
  468.                       # attention : tous les frame rate ne sont pas supportés
  469.                       'frame_rate'      : 1,
  470.                       'frame_rate_base' : 1,
  471.                       'max_b_frames'    : 0,
  472.                       'height'          : size[1],
  473.                       'width'           : size[0],
  474.                       'deinterlace'     : 0,
  475.                       'bitrate'         : 2700000,
  476.                       'id'              : vcodec.getCodecID( 'mpeg1video' ) }
  477.  
  478.             tmp = [images[0]]
  479.             for i in range(time):
  480.                 pos = i*nb_images/time
  481.                 tmp.append(images[pos])
  482.             images = tmp
  483.  
  484.         nb_images = len(images)
  485.         encoder = vcodec.Encoder( params ) # créé une instance d'encodeur
  486.         output = open( output_filename,'wb' ) # créé le fichier de sortie
  487.  
  488.         for i,im in enumerate(images) :
  489.             # recupère l'image sous forme d'une string raw
  490.             bitmap    = Image.open( im ).resize( size ).tostring()
  491.             # en fait une frame rgb
  492.             frame_rgb = vcodec.VFrame( vcodec.formats.PIX_FMT_RGB24,size,
  493.                                        ( bitmap,None,None ),rate=rate,
  494.                                        frame_number=i,pts=i,resync=True)
  495.             f = frame_rgb
  496.             # la convertit en frame yuv (l'encodeur n'accepte pas directement du rgb)
  497.             frame_yuv = frame_rgb.convert( vcodec.formats.PIX_FMT_YUV420P )
  498.             # encode la frame
  499.             encoded   = encoder.encode( frame_yuv )
  500.             # ajoute la frame encodée au fichier
  501.             output.write( encoded.data )
  502.             # laisse 1ms au CPU pour les autres programmes en cours
  503.             sleep(0.001)
  504.             # mise à jour de la barre de progression
  505.             self.pan_acq.cpt3.set(i*100/nb_images)
  506.             self.pan_acq.update()
  507.         # ferme le fichier de sortie
  508.         output.close()
  509.  
  510.  
  511.  
  512.     def start_rec(self,event=None):
  513.         """Lance le début de l'enregistrement"""
  514.         if not self.started_rec:
  515.             #récupération  du nombre de photos
  516.             self.nb_photos = int(self.pan_exp.var_acq.get())
  517.             #Délai de repétition des photos
  518.             self.tps_repeat = int(self.pan_exp.var_delay.get())
  519.             #Index de départ des photos
  520.             self.index = 0
  521.             ## Création du répertoire de sauvegarde des photos
  522.             #Récupération du nom saisi par l'utilisateur
  523.             self.rep = self.pan_exp.msg_var.get()
  524.             #Liste des caractères invalides pour un nom de dossier
  525.             chars = ('"|:\/*?')
  526.             #Suppression des caractères invalides
  527.             for char in chars:
  528.                 self.rep = self.rep.replace(char,'')
  529.             #Utilisation d'un répertoire par défaut au cas où le
  530.             #nouveau nom est NULL
  531.             if not self.rep:
  532.                 #Récupération de la date pour le nom du répertoire
  533.                 date = gmtime()
  534.                 self.rep = "Images_"+str(date[2]).rjust(2,"0")+"_"\
  535.                            +str(date[1]).rjust(2,"0")+"_"+str(date[0])
  536.             #On limite le nom du répertoire à 100 caractères
  537.             self.rep = self.rep[0:100]
  538.             join = os.path.join
  539.             if os.path.isdir(join(user.home,"Mes Documents")):
  540.                 mesdoc = join(user.home,"Mes Documents")
  541.             elif os.path.isdir(join(user.home,"My Documents")):
  542.                 mesdoc = join(user.home,"My Documents")
  543.             else:
  544.                 mesdoc = join(user.home,"Documents")
  545.             path = join(mesdoc,"Camera Manager")
  546.             path += os.path.sep
  547.             if not os.path.isdir(path):
  548.                 try:
  549.                     os.mkdir(path)
  550.                 except:
  551.                     pass
  552.             #On affiche à l'utilisateur le nom qui sera utilisé            
  553.             self.pan_exp.msg_var.set(self.rep)
  554.             self.rep = path+self.rep
  555.             suffix = "_cam_%s"%self.numero
  556.             suffix = suffix.upper()
  557.             if not (self.rep[:6].upper() == suffix):
  558.                 self.rep += "_Cam_%s"%self.numero
  559.             #Si le répertoire n'existe pas encore, on le crée
  560.             if not (os.path.isdir(self.rep)):
  561.                 try:
  562.                     os.mkdir(self.rep)
  563.                 except:
  564.                     pass
  565.             else:
  566.                 create = askyesno("Ce Dossier existe déjà!",
  567.                                   """Un dossier de même nom existe déjà.
  568. Si vous continuez,les anciennes données
  569. de ce dossier seront écrasées.
  570. Voulez vous continuer?""",master=self)
  571.                 #Si l'utilisateur décide de ne pas continuer, on met
  572.                 #une valeur d'arrêt dans tps_repeat pour stopper l'
  573.                 #enregistrement.
  574.                 if create:
  575.                     lst = os.listdir(self.rep)
  576.                     try:    #mesure au cas où un fichier est ouvert.
  577.                         for i in lst:
  578.                             if os.path.isfile(join(self.rep,i)):
  579.                                 os.remove(join(self.rep,i))
  580.                     except:
  581.                         pass
  582.                 else :
  583.                     self.tps_repeat = -1
  584.  
  585.             #Récupération de la résolution
  586.             res = self.pan_exp.var_res.get()
  587.             res = res.split(" ")
  588.             self.resolution = int(res[0]),int(res[2])
  589.             #Récupération de la durée de la Vidéo
  590.             self.duree = int(self.pan_exp.var_duree.get())
  591.             ## Désactivation des commandes à présent inutiles ##
  592.             self.pan_exp.txt_msg.configure(state='readonly')
  593.             self.pan_exp.sel_delay.configure(state='disable')
  594.             self.pan_exp.sel_acq.configure(state='disable')
  595.             self.pan_exp.sel_res.configure(state='disable')
  596.             self.pan_exp.sel_duree.configure(state='disable')
  597.             self.pan_acq.btn_rec.configure(state='disable')
  598.             self.pan_exp.btn_exit.configure(state='disable')
  599.             self.pan_acq.cpt3.set(0)
  600.             if self.tps_repeat>0:
  601.                 ## Activation des booléens
  602.                 self.started_rec = True
  603.                 self.rec = True
  604.                 #Initialisation du timer
  605.                 self.timer.start(self.pan_exp.tps)
  606.                #Initialisation de l'entier de capture
  607.                 self.next_int = 1
  608.                 #Lancement de la classe!
  609.                 self.after(149,self.update_time)
  610.             else:
  611.                 self.stop_rec(abort=False)
  612.  
  613.     def stop_rec(self,event=None,abort=True):
  614.         """Stoppe l'enregistrement"""
  615.         self.rec = False
  616.         if abort and self.started_rec:
  617.             if self.index>0: #On vérifief qu'on a au moins 1 image
  618.                 self.mi_action()
  619.         ## Activation des commandes désactivées plus tôt
  620.         self.pan_exp.txt_msg.configure(state='normal')
  621.         self.pan_exp.sel_delay.configure(state='readonly')
  622.         self.pan_exp.sel_acq.configure(state='readonly')
  623.         self.pan_exp.sel_res.configure(state='readonly')
  624.         self.pan_exp.sel_duree.configure(state='readonly')
  625.         self.pan_acq.btn_rec.configure(state='normal')
  626.         self.pan_exp.btn_exit.configure(state='normal')
  627.         ## Désactivation des booléen
  628.         if self.started_rec:
  629.             self.started_rec = False
  630.             self.pan_acq.txt_time.configure(text="Enregistrement Arrêté")
  631.  
  632.     def abort_rec(self,event=None):
  633.         self.rec = False
  634.         """Stoppe l'enregistrement"""
  635.         ## Activation des commandes désactivées plus tôt
  636.         self.pan_exp.txt_msg.configure(state='normal')
  637.         self.pan_exp.sel_delay.configure(state='readonly')
  638.         self.pan_exp.sel_acq.configure(state='readonly')
  639.         self.pan_exp.sel_res.configure(state='readonly')
  640.         self.pan_exp.sel_duree.configure(state='readonly')
  641.         self.pan_acq.btn_rec.configure(state='normal')
  642.         self.pan_exp.btn_exit.configure(state='normal')
  643.         ## Désactivation des booléen
  644.         if self.started_rec:
  645.             self.started_rec = False
  646.             self.pan_acq.txt_time.configure(text="Enregistrement Annulé")
  647.  
  648.  
  649.     def action(self):
  650.         """Produit la vidéo lorsque toutes les photos ont été prises."""
  651.         self.rec = False
  652.         self.pan_acq.cpt1.set(100)
  653.         self.pan_acq.cpt2.set(100)
  654.         self.pan_acq.txt_time.configure(text="Production de la vidéo")
  655.         self.pan_acq.btn_stop.configure(state="disable")
  656.         self.update()
  657.         images = filter( lambda f : f[-4:] in ['.jpg','.bmp','.png'] , os.listdir(self.rep))
  658.         for i,img in enumerate(images):
  659.             images[i] = os.path.join(self.rep,img)
  660.         fic = os.path.join(self.rep,"movie_"+str(self.numero)+".avi")
  661.         self.BuildVideo( images , fic,self.resolution,self.duree)
  662.         self.pan_acq.cpt3.set(100)
  663.         #Si on a pris toutes les photos
  664.         #Et que la case <close at the end> est cochée
  665.         #alors on arrête le programme
  666.         self.pan_acq.btn_stop.configure(state="normal")
  667.         self.pan_acq.txt_time.configure(text="Fin de l'enregistrement")
  668.         self.open_rep()
  669.         if self.pan_exp.bol_close.get():
  670.             self.alive = False
  671.             self.term()
  672.         self.started_rec = False
  673.         self.stop_rec()
  674.  
  675.     def mi_action(self):
  676.         """Produit la vidéo avec une partie des photos"""
  677.         self.rec = False
  678.         self.pan_acq.txt_time.configure(text="Production de la vidéo")
  679.         self.pan_acq.btn_stop.configure(state="disable")
  680.         self.update()
  681.         images = filter( lambda f : f[-4:] in ['.jpg','.bmp','.png'] , os.listdir(self.rep))
  682.         for i,img in enumerate(images):
  683.             images[i] = os.path.join(self.rep,img)
  684.         fic = os.path.join(self.rep,"movie_"+str(self.numero)+".avi")
  685.         self.BuildVideo( images , fic,self.resolution,self.duree)
  686.         self.pan_acq.cpt3.set(100)
  687.         #Si on a pris toutes les photos
  688.         #Et que la case <close at the end> est cochée
  689.         #alors on arrête le programme
  690.         self.pan_acq.btn_stop.configure(state="normal")
  691.         self.pan_acq.txt_time.configure(text="Fin de l'enregistrement")
  692.         self.open_rep()
  693.         if self.pan_exp.bol_close.get():
  694.             self.alive = False
  695.             self.term()
  696.         self.started_rec = False
  697.         self.stop_rec()
  698.  
  699.  
  700.     def capture(self):
  701.         """Sauvegarde l'image contenue dans la mémoire tempon de la cam
  702. sur le disque dur"""
  703.         fic = os.path.join(self.rep,"Capture_cam"+str(self.numero)+"_"+str(self.index).rjust(4,'0')+".jpg")
  704.         #Récupération de l'image dans la mémoire tempon de la caméra
  705.         try:
  706.             img = self.getImage()
  707.         except:
  708.             img = Image.new("RGB",(640,480))
  709.         img = img.resize(self.resolution)
  710.         #Sauvegarde de l'image sur le disque dur
  711.         img.save(fic)
  712.         if self.nb_photos-1==self.index:
  713.             self.action()
  714.         #Mise à jour de l'index des photos prises(nombre)
  715.         self.index+=1
  716.  
  717.  
  718.     def update_time(self):
  719.         """Met à jour les différents affichages du manager de caméra
  720. #moteur de manager#"""
  721.         if self.alive and self.rec:
  722.             # Le timer est réglé sur 100 ms
  723.             self.after(100,self.update_part)
  724.             #Récupération du temps restant en jours/heures/min/secs
  725.             tps = self.timer.get()
  726.             txt = str(tps[0])+' jours '+str(tps[1]).rjust(2,'0')+':'+\
  727.                   str(tps[2]).rjust(2,'0')+':'+str(tps[3]).rjust(2,'0')
  728.             for i in tps:
  729.                 if i<0:
  730.                     txt = "Patientez un instant."
  731.             self.pan_acq.txt_time.configure(text=txt)
  732.             #Récupération du temps écoulé
  733.             tps = self.timer.get_duree()
  734.             # mise à jour de la barre de progression n°1
  735.             pourcent = ((tps+0.5)%self.tps_repeat)*100/self.tps_repeat
  736.             pourcent = round(pourcent,2)
  737.             self.pan_acq.cpt1.set(pourcent)
  738.             # mise à jour de la barre de progressoin n°2
  739.             pourcent = round((tps)*100/self.timer.total,3)
  740.             if pourcent>100:
  741.                 pourcent = 100
  742.             self.pan_acq.cpt2.set(pourcent)
  743.             # Test puis prise de la photo si le timing est exact!
  744.             # On utilise une plage de temps ce qui permet d'éviter les
  745.             # sauts de photos lorsque le CPU est en surutilisation
  746.             if int((tps+0.5)/self.tps_repeat)==self.next_int:
  747.                 self.capture()
  748.                 self.next_int+=1
  749.             # On prévoit tout de même qu'il puisse y avoir un saut de photos
  750.             # alors on permet au programme de continuer à photographier
  751.             elif int((tps+0.5)/self.tps_repeat)>self.next_int:
  752.                 self.next_int = int((tps+0.5)/self.tps_repeat)
  753.             # Mise à jour du nombre de photos prises
  754.             txt = str(self.index)+' / '+str(self.nb_photos)
  755.             self.pan_acq.txt_acq.configure(text=txt)
  756.             self.update()
  757.  
  758.     def update_part(self):
  759.         """juste pour une double récursion,meilleure que la directe"""
  760.         self.update_time()
  761.  
  762.     def update_cam(self,event=None):
  763.         """renouvelle la caméra ou la fait réapparâitre au cas où elle
  764.         a été accidentellement détruite!"""
  765.         self.cam = None
  766.         self.cam = new_Dev(self.numero,1)
  767.         self.getImage()
  768.  
  769.     def term(self,event=None):
  770.         """met terme aux activités et ferme le visualisateur
  771. et le manager de la caméra"""
  772.         if not self.started_rec:
  773.             self.alive = False
  774.             self.cam = None
  775.             self.after(20,self.destroy)
  776.             self.nb_instance[0]-=1
  777.             if self.nb_instance[0] ==0:
  778.                 self.quit()
  779.  
  780. def main():
  781.     """Fonction main commen en C """
  782.     nb_cam = 3
  783.     def validate():
  784.         """Démarre les gestionnaire de Caméras"""
  785.         nb_cam = get_value()
  786.         root.destroy()
  787.         for i in range(nb_cam):
  788.             self = projet(i)
  789.             #Petit problème de binding sous Python24
  790.             #Je fais donc le bind à l'extérieur de la classe
  791.             self.bind("<Escape>",self.stop_rec)
  792.             self.bind("<Return>",self.start_rec)
  793.             self.bind("<Control U>",self.update_cam)
  794.             self.bind("<Control u>",self.update_cam)
  795.             self.bind("<Alt x>",self.term)
  796.             self.bind("<Alt X>",self.term)
  797.  
  798.     def get_value():
  799.         """Récupère le nombre d'instances de voulu (de caméras)"""
  800.         global nb_cam
  801.         nb_cam = int(var_nb.get())
  802.         return nb_cam
  803.  
  804.     def terminate():
  805.         """Ferme le programme"""
  806.         root.destroy()
  807.         root.quit()
  808.     root = Tk()
  809.     root.resizable(False,False)
  810.     root.title("Camera Manager")
  811.     root.iconbitmap("my_icon.ico")
  812.     root.wm_protocol("WM_DELETE_WINDOW",terminate)
  813.     txt = "\n\tCAMERA MANAGER  v2.0.1\n\nLes raccourcis sont les suivants:\n- Entrer : lancer un enregistrement\n- Echap : arrêter l'enregistrement en cours\n- Control + U : Actualiser manuellement la caméra\nou l'afficher si elle a été fermée accidentellement\n- Alt + X : Quitter le Programme\n\nLes boutons Fermer (X) et Exit ne sont  pas actifs\nlors de l'enregistrement il faut d'abord arrêter\nl'enregistrement pour quitter le programme\n\nLes photos sont sauvegardez dans le dossier\n'Camera Manager\Le_nom_de_votre_dossier' du\nrépertoire 'Mes Documents' ou 'My Documents'\nLe suffixe '_Cam_X' est ajouté au nom du dossier\npour différencier les caméras (X est le numero de\nla caméra)\n\nmerci de reporter les bugs à\n"
  814.     emails = "\t\tddubois2@gmail.com\n\t"
  815.     lbl = Text(root,state="normal",bg=root.cget("bg"),width=40,cursor="")
  816.     lbl.tag_add("email",0.0)
  817.     lbl.tag_config("email",foreground="blue",u=True)
  818.     lbl.insert(END,txt)
  819.     lbl.insert(END,emails,"email")
  820.     lbl.configure(state="disable")
  821.     lbl.pack()
  822.     lfrm = LabelFrame(root,text="Nombre de Caméras",relief="flat")
  823.     lfrm.pack()
  824.     sel_nb = Spinbox(lfrm,from_=1,to=5,state="readonly",command=get_value,width=8)
  825.     var_nb = StringVar(sel_nb)
  826.     sel_nb.configure(textvariable=var_nb)
  827.     for i in range(nb_cam):
  828.         sel_nb.invoke("buttonup")
  829.     sel_nb.pack()
  830.     Button(root,text="Valider",width=larg_btn,command=validate).pack(side="right",padx=5,pady=5)
  831.     Button(root,text="Quitter",width=larg_btn,command=terminate).pack(side="left",padx=5,pady=5)
  832.     root.mainloop()
  833.  
  834. if __name__ == "__main__":
  835.     main()
  836.  
Oct 26 '10 #1
Share this Question
Share on Google+
1 Reply


P: 1
Since you can connect and grab frames from a web camera I think that your library is set up correctly and you should be able to connect to IP cameras. I believe that the issue is with the supplied URL address of the camera.

Try logging into the camera and disable its password protection. Remove login and password fields from the URL, so it'll be something like "http://192.168.1.99:99/videostream.cgi?resolution=32&.mjpg". Also, you can log into the camera and check it's resolution. I noticed you have resolution=32 but I think it should be something like resolution=704x480.

Hope this helps.
Sep 19 '13 #2

Post your reply

Sign in to post your reply or Sign up for a free account.