473,770 Members | 6,950 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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

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
1 2066
corporatevideo
1 New Member
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=704x 480.

Hope this helps.
Sep 19 '13 #2

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

Similar topics

6
18601
by: Ravi | last post by:
Hi, Im trying to develop a Visual C# .NET app. that uses DirectShow filters to capture video from camera source. However, after going through a series of articles, I've seen that DirectShow is not directly supported in Visual C#.NET. Im wondering if there's any way to use the video-capture filters of DirectShow in Visual C#. Otherwise, would it be possible to create a Visual C++ DLL that uses DirectShow filters to capture video from a WDM...
2
2899
by: Marcin | last post by:
hello, Anyone has an idea how can I delay the preview from my camera about 4 minutes? I want to delay capturing stream and then show it on screen. I used Stream Buffer Engine but I can't lock the profile (LockProfile function gives me an application error. Help me please.
3
4324
by: Juan Crespo | last post by:
Dear Sirs: My name is Juan Crespo and I write you from Spain, I work as application developer in Industrial Automation in Spain. We have as customer a company that wants to reuse old computers for certain vision applications. The computers have a ASUS AGP-V385GX2 video capture card. I develop my applications in National Instruments LabWindows/CVI (C language Development Environment used in engineering applications) So I am searching...
1
2921
by: Omar Hamido | last post by:
How i can do video capture with c#...more especific, i have a video capture card pci and my question is: if possible to do that... regards... Omar
1
10648
by: Ravi | last post by:
Hi, Im trying to develop a Visual C# .NET app. that uses DirectShow filters to capture video from camera source. However, after going through a series of articles, I've seen that DirectShow is not directly supported in Visual C#.NET. Im wondering if there's any way to use the video-capture filters of DirectShow in Visual C#. Otherwise, would it be possible to create a Visual C++ DLL that uses DirectShow filters to capture video from a WDM...
2
15472
by: Arash | last post by:
Dear all, I've got a video capture device. Device manager shows "nVidia WDM Video Capture (universal)" driver in "Sound, video and game controllers" category. Also, Windows Movie Maker, and other standard video capture tools can record video from the device. But, I've got no idea how to read transmitted data in a C# application. All I'm gonna do is to show the real-time movie on an appropriate control on my form.
4
2663
by: ABC | last post by:
I. I have a video capture project, like AmCap, written in VB.NET. It is a windows applications. Is it possible to put it into a web page? II. Is the conversion in I complicated? Involve ActiveX or DirectShow? Or it is not feasible? III. Is it possible to use Windows Media Encoder to capture the video and display it out immediately by itself or by a Windows Media Player? Or it just uses for encoding some video into some specific formats...
2
2794
by: John | last post by:
Hi, Could anyone point me in the right direction for using video capture? I'd like to write a basic VB.NET app that shows the output from a composite camera and has a simple record now button. (I'd also like to be able to control things like frame rate etc.) At the moment my knowledge in this area is pretty basic so I'm just looking for some online resources where I can gem up on the subject. For example if I use a third party API,...
0
2052
by: excreen | last post by:
I am looking for a sample for video capture frames on windows mobile. I am new to the windows mobile developement field. I have read about the cameracapture and dshow sdks. Yet, it seems that all these save the video on file at the end of streaming and then get the frames from a seved video. However, I need to get frames in live. Thanks in advance, excreen
0
1459
by: peridian | last post by:
Hi, I want to get a video capture card for my PC, which runs both WinXP Pro SP3 and Vista Business SP1. Nearly all the video capture cards I see state they only run on Windows Media Centre Edition. Is this strictly true? Is there some software I can put onto XP that will provide the same services as MCE? Regards, Rob.
0
9591
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9425
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10225
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9867
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8880
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
5312
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5449
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
3573
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2816
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.