Rebol et OpenCV
ldci6-Jul-2013/1:24:27+2:00
Bien comme on a perdu le fil, j"en crée un nouveau.
Juste pour vous dire que je remonté un vieux Dell Inspiron pour faire des tests et oh, merveille, tout le code fonctionne parfaitement sous windows XP. Il me reste à tester la vidéo dans les jours qui viennent ...
Vous pouvez toujours récupérer ici
http://www.wuala.com/fjouen/Code/OpenCV/REBOL/samples/

Bon c'est promis, je vais passer sous GitHub ... ASAP
ldci6-Jul-2013/16:36:01+2:00
Bien
A part le problème de mémoire, la gestion des caméras est également parfaite avec windows ! D'après ce que j'ai pu lire, le garbage collector de Rebol s'en remet à l'OS pour les structures grosses consommatrices de mémoire. Va falloir que je trouve comment Rebol délègue cette mission à l'OS.
A +
ldci10-Jul-2013/19:55:23+2:00
Des infos intéressantes à propos de la gestion de la mémoire avec Rebol/OpenCV

Pas évident, car a première vue on n’a pas de GC en C et en C++ : on doit gérer la mémoire soi même.
Le principe de base d'opencv: quand on crée une structure (image, matrice…) on doit utiliser une fonction release
Exemple:
   cvCreateCapture -> cvReleaseCapture
cvCreateImage -> cvReleaseImage

Malheureusement, les fonctions cvRelease ne fonctionnent pas correctement avec Rebol car je pense que Rebol et OpenCV gèrent différemment le malloc associé à la création de la structure et la façon dont ils renvoient la structure. C ou C ++ (et Red/System) renvoient un pointeur (donc une adresse vers la structure) et Rebol une structure considérée comme un pointeur (on doit récupérer l’adresse de la structure soi-même).

Exemple de l’utilisation mémoire avec print stats / (10 ** 6)

Avant la création de la structure image par cvCreateImage       : 6.093174
Après la création de la structure                    : 6.099702
Après le release de la structure par cvReleaseImage          : 6.104198

On ne libère pas la mémoire !!!

La solution qui fonctionne est de gérer soi-même la libération de la mémoire avec Rebol en utilisant la fonction free-mem de Nenad
free-mem: func ['word] [set :word make none! recycle]

Avant la création de la structure image par cvCreateImage       : 6.093174
Après la création de la structure                    : 6.099702
Après le release de la structure free-mem image            : 5.066818

On libère bien la mémoire allouée !!

Cette technique fonctionne pour les images créées ou chargées
Voici un bon moyen de gérer les fuites mémoire d’OpenCV

Le seul cas où cette technique ne fonctionne pas c’est quand les images proviennent de la caméra ou d’un film vidéo. Dans ce cas, la mémoire est gérée par le « driver vidéo » et échappe à notre code. Ceci n’est pas spécifique à Rebol, mais à OpenCV. Le problème est qu’a vraiment un « memory leak » et pour ce cas je n'ai pas encore trouvé de solution efficace.
Le bon point c'est que ce n'est pas lié au GC de Rebol

A +
ldci11-Jul-2013/20:58:47+2:00
La suite des aventures avec les webcams!

Pour la fuite mémoire, pas de pb avec Red/System ou avec du C. Pour Rebol, le GC fait son travail à intervalles réguliers : il suffit de mettre l’image issue de la webcam à none pour que le GC fonctionne et libère bien la mémoire:
Exemple :
foo: 0
; repeat until q keypress (key:  #"q"; 113 as integer)

while [foo <> 113] [
	image:  cvQueryFrame capture ; get image
        cvShowImage "Test Window"  image   ; show frame
        print ["used : " system/stats / (10 ** 6)] ; used memory
        image: none ; free image
        foo: cvWaitKey 1
]


Bien, ce n'était pas évident, mais ça marche. Dernier point: Il ne faut surtout pas appeler un recycle à l’intérieur de la boucle, sinon le GC s’affole et ne sert plus à rien (je crois que ce point est documenté chez RT).
Ah Rebol
ldci14-Jul-2013/20:22:46+2:00
Suite et fin ...

Le dernier point à régler est la fonction cam2Rebol qui pose pb :
A première vue, l’utilisation de timers entraîne un memory leak !!! (cf rambo)

Am Freitag, 17. Oktober 2003 00:05 schrieb Terry Brownell:
➢   I've noticed a memory leak when you hover a mouse over any face using the > "feel" user interface events. Is this a known bug or ? If you run the > example below, and watch the memory usage of the Rebol.exe running it, it > will go up when you hover. Same thing with the engage feel. >

Après une série de tests, l’utilisation de timers n’entraîne pas de memory leak. Ce point a dû être réglé par RT dans les mises à jour. C’est bien la fonction de conversion OpenCV to Rebol qui pose pb uniquement pour les images issues d’une caméra.

Fondamentalement, cette fonction récupère le contenu binaire de l’image OpenCV via un pointeur puis crée une image rebol qui est renvoyée vers une face de type image (exemple : isu/image : cam2Rebol imageCV.

cam2Rebol: func [src /local data im] [
	rgb: get-memory src/imageData src/imageSize 
	rgb: reverse data
	im: make image! reduce [as-pair (src/width) (src/height) rgb]
]


Rien de bien sorcier en soi : les données sont bien récupérées et affichées correctement dans le widget. Par contre chaque appel à cette fonction augmente le mémoire consommée et provoque un crash quand la mémoire est épuisée.
J’ai d’abord suspecté Rebol de me créer autant d’instance de l’image que d’appel à la fonction. Mais ce n’est pas le cas :

for i 1 10000 1 [
rgb: 0.0.0
	im: make image! reduce [512x512 rgb]
	visu/image: im
	visu/image/text: join to-string i [": Used Mem: " round/to stats / (10 ** 6) 0.01]
	show visu
]


n’entraîne pas de consommation de mémoire et le GC fait son travail.

J’ai donc pensé ensuite à un pb avec le get-memory. J’ai donc remplacé rgb: get-memory src/imageData src/imageSize par rgb: 0.0.0 sans succès : toujours une fuite mémoire.
Il y a bien un problème avec la fonction cvQueryFrame capture (grab and retrieve image) avec Rebol qui se comporte comme si chaque image recueillie était une nouvelle instance de la structure IplImage ! (expliquant ainsi la fuite de mémoire).

Finalement, la solution consiste à ne pas demander à Rebol de transformer les images et de laisser OpenCV faire les affichages dans son propre espace graphique:

image: cvQueryFrame capture ; grab and retrieve image
cvShowImage « testWindow » image

Avec cette technique plus de problème : l’affichage par OpenCV ne joue pas sur le GB de Rebol qui assure correctement son travail.

Comme je n’ai pas ce problème avec Red/System, je pense vraiment que cette difficulté est liée à la façon dont Rebol traite les structures renvoyées par les routines OpenCV (cf. supra)

A suivre …
PierreCh16-Jul-2013/12:20:27+2:00
Ce problème, il survient avec Rebol 3?
ldci16-Jul-2013/21:35:33+2:00
@PierreCh: pour l'instant je n'ai pas investi Rebol3 qui n'est pas stabilisé (notamment avec Mac OSX) et ne possède pas beaucoup de documentation.
PierreCh16-Jul-2013/23:39:29+2:00
Oui, j'en suis un peu au même stade...

Mais au moins, avec Rebol 3, nous eûssions pu savoir, en nous plongeant dans son code, d'où venait l'âne au Mali.
ldci18-Jul-2013/17:29:01+2:00
allez une petite image
http://www.wuala.com/fjouen/Code/OpenCV/REBOL/pub/4Cams.jpg/

Comment gérer 4 cameras (ou plus) avec rebol ou red. Chaque caméra est indépendante des autres et peut avoir son propre FPS.
A plus
PierreCh25-Jul-2013/18:35:51+2:00
Youpi, j'ai retrouvé une trace du fil précédent, qui s'était perdu:

http://web.archive.org/liveweb/http://www.digicamsoft.com/cgi-bin/rebelBB.cgi?thread=%3C25May2012200150764026200%3E
PierreCh25-Jul-2013/18:40:47+2:00
Ah non, mince, pardon; j'ai causé trop vite, il n'y a pas tout le fil... :-s
ldci12-Sep-2013/15:11:50+2:00
Salut à tous
De retour sur le site avec de bonnes nouvelles pour openCV

J'ai mis à jour les libs (à récupérer sur Wuala) ainsi que le fichier opencv.r

Pour simplifier le travail de ceux qui veulent faire des tests, j'ai introduit une fonction qui permet de sélectionner la version (1.0.0 ou 2.0.0) d'opencv et ce en fonction de son OS.
Bon évidement on peut adapter selon ses propres besoins

usedLib: func [version [tuple!]] [
	runningOs: getOs
	if runningOs = "Mac OS X" [
		switch version [
			1.0.0 [ocv: load/library %/Library/Frameworks/OpenCV1-0.framework/Versions/A/OpenCV]
			2.0.0 [ocv: load/library %/Library/Frameworks/OpenCV2-0.framework/Versions/B/OpenCV]
		]
		cvision: ocv highgui: ocv cxcore: ocv
	]
	
	if runningOs = "Windows" [
		switch version [
			1.0.0 [
				cxcore: load/library to-file "c:\windows\system32\cxcore100.dll"
				cvision: load/library to-file "c:\windows\system32\cv100.dll"
				highgui: load/library to-file "c:\windows\system32\highgui100.dll"
			]
			2.0.0 [
				cxcore: load/library to-file "c:\OpenCV2.0\bin\libcxcore200.dll"
				cvision: load/library to-file "c:\OpenCV2.0\bin\libcv200.dll"
				highgui: load/library to-file "c:\OpenCV2.0\bin\libhighgui200.dll"
			]
		]
	]
	
	if runningOs = "linux" [
		switch version [
			2.0.0 [
				cxcore: load/library to-file "/usr/lib/libcxcore.so.2.1"
				cvision: load/library to-file "/usr/lib/libcv.so.2.1"
				highgui: load/library to-file "/usr/lib/libhighgui.so.2.1"
			]
		]
	]
]

; l'appel est enfantin

opencvVersion: 2.0.0
usedLib opencvVersion



L'autre bonne nouvelle est qu'un étudiant de Master rejoint le projet: il va pouvoir améliorer et optimiser le portage? Cool, non?

A +
ldci19-Sep-2013/21:55:19+2:00
Allez pour mettre un peu d'animation sur le site ...



Rebol et OpenCV, c'est génial
ldci19-Sep-2013/21:56:10+2:00
Allez pour mettre un peu d'animation sur le site ...



Rebol et OpenCV, c'est génial
ldci19-Sep-2013/21:56:39+2:00
Allez pour mettre un peu d'animation sur le site ...



Rebol et OpenCV, c'est génial
ldci19-Sep-2013/21:56:52+2:00
Allez pour mettre un peu d'animation sur le site ...



Rebol et OpenCV, c'est génial
ldci20-Sep-2013/13:22:59+2:00
désolé
Je ne sais pas ce qu'il s'est passé avec l'image findfaces.jpg

http://www.wuala.com/fjouen/Code/OpenCV/REBOL/pub/findfaces.jpg/


en tout cas voici le code qui permet de retrouver des visages dans une image
findFaces: does [
	; looks for n faces in image  use the fastest variant
	
	if isImage [cvZero isource isource: cvLoadImage file CV_LOAD_IMAGE_UNCHANGED  cvShowImage "Input" isource] 
	faces: cvHaarDetectObjects babyface cascade storage 1.1 2 CV_HAAR_DO_CANNY_PRUNING 20 20
	
	for i 1 faces/total 1
	[
		faceRect: cvGetSeqElem faces i 0 ; we get a pointer to 4 integers
	    x: to-integer reverse get-memory faceRect + 0 4 
		y: to-integer reverse get-memory faceRect + 4 4
		wd: to-integer reverse get-memory faceRect + 8 4
	    hg: to-integer reverse get-memory faceRect + 12 4	
	    roi: cvRect (x * scale) (y * scale) ((x + wd) * scale) ((y + hg) * scale)
	    cvRectangle isource roi/x roi/y roi/width roi/height  0 255 0 0 thickness lineType 0
	]
	cvShowImage "Input" isource	
]

ldci20-Sep-2013/13:23:10+2:00
désolé
Je ne sais pas ce qu'il s'est passé avec l'image findfaces.jpg

http://www.wuala.com/fjouen/Code/OpenCV/REBOL/pub/findfaces.jpg/


en tout cas voici le code qui permet de retrouver des visages dans une image
findFaces: does [
	; looks for n faces in image  use the fastest variant
	
	if isImage [cvZero isource isource: cvLoadImage file CV_LOAD_IMAGE_UNCHANGED  cvShowImage "Input" isource] 
	faces: cvHaarDetectObjects babyface cascade storage 1.1 2 CV_HAAR_DO_CANNY_PRUNING 20 20
	
	for i 1 faces/total 1
	[
		faceRect: cvGetSeqElem faces i 0 ; we get a pointer to 4 integers
	    x: to-integer reverse get-memory faceRect + 0 4 
		y: to-integer reverse get-memory faceRect + 4 4
		wd: to-integer reverse get-memory faceRect + 8 4
	    hg: to-integer reverse get-memory faceRect + 12 4	
	    roi: cvRect (x * scale) (y * scale) ((x + wd) * scale) ((y + hg) * scale)
	    cvRectangle isource roi/x roi/y roi/width roi/height  0 255 0 0 thickness lineType 0
	]
	cvShowImage "Input" isource	
]

PierreCh20-Sep-2013/23:55:57+2:00
En effet, cela a l'air rigolo!
ldci10-Mar-2014/14:26:27+1:00
Salut à tous
Comme je vous l'avais annoncé il y a quelque temps, je suis en train de revoir tout le portage OpenCV vers Rebol et Red avec un de nos étudiants.
J’aurais besoin de vos idées pour un petit problème.
Comme l’avait bien documenté François Vanzeveren (vieux site Rebol ), Le type REBOL Struct ! n’est pas identique à une structure en C, car une structure REBOL est interprétée comme un pointeur, c’est-à-dire l’équivalent de struct* en C.
Cela facilite l'accès au libraires externes qui font appel aux pointeurs. Ceci étant on a un problème lorsque la routine renvoie une C structure et non un pointeur comme dans l’exemple : CVAPI(CvSize) cvGetSize( const CvArr* arr ).
La structure renvoyée CvSize contient deux entiers : width et height
L'implémentation suivante en rebol ne fonctionne pas car elle ne renvoie que le premier entier et non les deux

cvGetSize: make routine! compose/deep/only [
Returns width and height of array in elements
	arr				[struct! (first CvArr!)]
	return:			[integer! integer!]; CvSize not a pointer	
] cxcore "cvGetSize"


le reduce [integer! integer!] ne marche pas non plus.
Qui aurait une idée lumineuse?
DocKimbel12-Mar-2014/10:58:22+1:00
Tu peux tenter de renvoyer un type decimal! et tu y accèdes en mode binaire ensuite pour extraire les deux entiers 32 bits.
ldci7-Apr-2014/13:31:10+2:00
Des nouvelles de la gestion de la mémoire. Bon à savoir
J'ai trouvé pour les problèmes de consommation mémoire! http://www.rebol.com/docs/library.html#Garbage
Il suffit de protéger les structures passées en paramètres aux routines pour éviter qu'elles tombent dans les oubliettes du Garbage Collector de Rebol avec [save]
Exemple

IplImage!: make struct! compose/deep/only [
	[save]													; specific to rebol to inhibe GC ;
    nSize 				[integer!]							; sizeof(IplImage)
    ID 					[integer!]							; version (=0)
    nChannels 			[integer!]							; Most of OpenCV functions support 1,2,3 or 4 channels
   	alphaChannel 		[integer!]							; Ignored by OpenCV */
    depth 				[integer!]							; Pixel depth in bits: 
    colorModel 			[integer!]							; Ignored by OpenCV char [4]
    channelSeq 			[integer!]							; ditto *
    dataOrder 			[integer!]							; 0 - interleaved color channels, 1 - separate color channels.
    origin 				[integer!]							; 0 - top-left origin, 1 - bottom-left origin (Windows bitmaps style). 
    align 				[integer!]							; Alignment of image rows (4 or 8).OpenCV ignores it and uses widthStep instead.
    width 				[integer!]							; Image width in pixels
    height 				[integer!]							; Image height in pixels. `
    roi					[int]; [struct! (first IplROI! )]   ; Image ROI. If NULL, the whole image is selected  we absolutely need  a pointer to IplRoi! structure when using routines with a ROI
    maskROI 			[int]; [struct! (first IplImage!)]	; Must be NULL [0]. IplImage! : pointer to maskROI if any
    imageId 			[int] ;[void*]						; "           " 
    tileInfo 			[int] ;[struct! (first IplTileInfo! )]		; [int]; here also"           "
    imageSize 			[integer!]							; Image data size in bytes
    imageData 			[int]; [char*]						; Pointer to aligned image data.     
    widthStep 			[integer!]							; Size of aligned image row in bytes.    
    BorderMode 			[integer!]							; Ignored by OpenCV.                     
    BorderConst 		[integer!]							; Ditto.                                
    imageDataOrigin		[int]	    						; Pointer to very origin of image data 
] none 


Ca marche nickel et évite les fuites mémoires observées avant.

Login required to Post.


Powered by RebelBB and REBOL 2.7.8.4.2