OpenCV et Rebol V3 | |
ldci | 25-Jan-2015/16:02:04+1:00 |
Bonjour à tous les reboliens! Après avoir joué un peu avec OpenCV et Python, je suis en train de terminer la version 3 du portage d'OpenCV vers Rebol 2.7.8. J'ai revu environ 600 fonctions et il m'en reste quelques unes à terminer. Il y a plein de nouveautés pour jouer avec des images stéréo et autres ... Le code est compatible avec OPenCV2.4.9 et 2.4.10 et sera maintenu pour les nouvelles versions d'openCV. On peut également travailler avec la dll en static ou en dynamic à partir de Rebol J'ai beaucoup simplifié les appels aux fonctions C qui, sauf indication contraire renvoient un pointeur (une adresse sous forme d'entier). C'est plus simple pour programmer. J'ai aussi implémenté une fonction "magique" qui donne accès au contenu des structures si le besoin s'en fait sentir. getPointerValues: func [ptr [integer!] structureType [struct!]] [ "Gets the contents of opencv structures" struct: make struct! (structureType) none ; make a rebol structure for cv Structure content: get-memory ptr length? third struct ; get the content of the pointer change third struct content ; update rebol structure struct ; return structure ] L'appel est très simple: ; load image image: cvLoadImage filename CV_LOAD_IMAGE_COLOR; on charge l'image sous la forme d'un pointeur imageS: getPointerValues image IplImage! ; on récupère le contenu de la structure ;Create the color output image cedge: cvCreateImage imageS/width imageS/height IPL_DEPTH_8U 3 ; on se sert des valeurs de la structures pour créer une autre image On ne peut pas faire plus simple pour travailler sur toutes les structures OpenCV Voici encore un exemple qui montre comment transformer une image OpenCV en image rebol ;this is for memory alignment of IplImage in OpenCV; ; processes line by line ;get the line data with the ACTUAL size : width * nChannels and not widthStep cvtoRebol: func [img dest /local src rgb] [ "Transforms OpenCV image to REBOL image" src: getPointerValues img IplImage! ; get values of IplImage rgb: copy #{} ; make a binary for y 0 src/height - 1 1 [ index: y * src/widthStep ; go to line y and get data line: get-memory (src/imageData + index) (src/width * src/nChannels) append tail rgb line ] ; mow makes the REBOL image dest/image: make image! reduce [as-pair (src/width) (src/height) reverse rgb] dest/effect: [fit flip 1x1] ; show dest ] J'adore ce type de programmation: clair, concis et efficace. Tout REBOL quoi! | |
GreG | 26-Jan-2015/9:40:15+1:00 |
Merci de partager ces travaux avec nous Effectivement, OpenCV contient énormément de fonctions! François, sais-tu si il est possible de modulariser OpenCV de façon à construire une librairie OpenCV qui ne contient que les fonctions souhaitées? | |
ldci | 26-Jan-2015/10:38:24+1:00 |
Salut Greg, La réponse est oui. J'ai adopté l'approche en modules qui est développée par opencv depuis ses dernières versions if system/version/4 = 2 [ calib3d: load/library %/usr/local/lib32/opencv/libopencv_calib3d.dylib core: load/library %/usr/local/lib32/opencv/libopencv_core.dylib imgproc: load/library %/usr/local/lib32/opencv/libopencv_imgproc.dylib highgui: load/library %/usr/local/lib32/opencv/libopencv_highgui.dylib legacy: load/library %/usr/local/lib32/opencv/libopencv_legacy.dylib objectd: load/library %/usr/local/lib32/opencv/libopencv_objdetect.2.4.dylib photo: load/library %/usr/local/lib32/opencv/libopencv_photo.dylib video: load/library %/usr/local/lib32/opencv/libopencv_video.dylib ] Tu peux donc choisir le module qui t'intéresse. Ensuite il faut utiliser une fonction mezzanine qui te permet de charger les routines qui t'intéressent cvFunc: func [specs lib id] [make routine! specs lib id] Cette technique te permet de charger "à la volée" les fonctions opnecv dont tu as besoin. Voici un exemple qui illustre mon propos #! /usr/bin/rebol REBOL [ Title: "OpenCV Tests: Pyramids demo" Author: "François Jouen" Rights: "Copyright (c) 2012-2014 François Jouen. All rights reserved." License: "BSD-3 - https://github.com/dockimbel/Red/blob/master/BSD-3-License.txt" ] set 'appDir what-dir ocvDir: join appDir "libs/opencv/" do to-file join ocvDir "opencv249.r" ; for new opencv 2.4.9 do to-file join ocvDir "rtools.r" ; for memory management wName1: "Pyramids Demo" w: h: 0 nChannels: 3 ;some OpenCV constants CV_WINDOW_AUTOSIZE: 1 CV_GAUSSIAN_5x5: 7 IPL_DEPTH_8U: 8 CV_LOAD_IMAGE_COLOR: 3 ; external opencv functions we need cvNamedWindow: cvFunc [name [string!] flag [integer!] return: [ptr!]] highgui "cvNamedWindow" cvWaitKey: cvFunc [delay [integer!] return: [ptr!]] highgui "cvWaitKey" cvLoadImage: cvFunc [name [string!] flag [integer!] return: [ptr!]] highgui"cvLoadImage" cvShowImage: cvFunc [name [string!] img [ptr!]] highgui "cvShowImage" cvCreateImage: cvFunc [w [integer!] h [integer!] depth [integer!] channels [integer!] return: [ptr!]] cxcore "cvCreateImage" cvPyrUp: cvFunc [s [ptr!] d [ptr!] filter [integer!]] imgproc "cvPyrUp" cvPyrDown: cvFunc [s [ptr!] d [ptr!] filter [integer!]] imgproc "cvPyrDown" picture: to-string to-local-file join appDir "images/lena.jpg" src: cvLoadImage picture CV_LOAD_IMAGE_COLOR; CV_LOAD_IMAGE_GRAYSCALE; dst: tmp: src cvNamedWindow wName1 CV_WINDOW_AUTOSIZE c: 0 ivalues: getIPLValues/address tmp; get informations about the image w: ivalues/11 ; width h: ivalues/12 ;height while [c <> 27] [ c: cvWaitKey 10 if c > 0 [ ; u ; 117 if c = 117 [ w: ivalues/11 * 2 h: ivalues/12 * 2 print join to-char c [" Image size: " w " " h] dst: cvCreateImage w h IPL_DEPTH_8U nChannels cvPyrUp tmp dst CV_GAUSSIAN_5x5 ] ;d ; 100 if c = 100 [ w: ivalues/11 / 2 h: ivalues/12 / 2 if w >= 4 [ print join to-char c [" Image size: " w " " h] dst: cvCreateImage w h IPL_DEPTH_8U nChannels cvPyrDown tmp dst CV_GAUSSIAN_5x5 ] ] ] cvShowImage wName1 dst tmp: dst ivalues: getIPLValues/address tmp ] Cette technique fonctionne très bien, mais elle implique que tu charges tous les modules dont tu as besoin. L'idéal serait que REBOL soit capable d'aller chercher dans le module UNIQUEMENT les fonctions requises un peu comme modula2 le faisait ou comme python le fait avec la fonction import: "from SimpleCV import Camera". Si tu as une idée comment faire, elle est la bienvenue D'après mes échanges avec Nenad, cela ne semble pas évident ni avec Rebol ni avec Red. Dernier point, ce serait pas mal maintenant d'interfaçer opencv avec Rebol 3. Je n'ai pas encore eu vraiment le temps de m'intéresser à R3 et les dll, car j'ai passé pas mal de temps à optimiser les appels aux fonctions opencv et la constructions des structures de données openCV. Ca m'a permis de développer des algorithmes un peu sophistiqués pour traiter des images thermiques et autres joyeusetés. dans cette option recherche, j'ai vraiment besoin d'avoir accès aux paramétrages précis des fonctions opencv. Mais pour beaucoup d'applications, on peut simplifier. Une idée intéressante serait de faire un langage métier permettant de faire du "computer vision" simplement et avec REBOL. Ca existe en python (http://simplecv.org/) et c'est assez efficace. Evidemment, pour tout ça, il faut des bras | |
GreG | 26-Jan-2015/10:59:59+1:00 |
Atronix a implémenté FFI sur Rebol 3, ce qui facilite l'interfaçage avec des libs existantes. Quelques exemples: https://github.com/zsx/r3/blob/atronix/make/tests/test-ffi.r https://github.com/zsx/r3/blob/atronix/make/tests/ms-drives.r | |
ldci | 26-Jan-2015/21:30:19+1:00 |
Merci Greg pour le lien C'est très intéressant comme approche car c'est simple. Quelques problèmes à gérer sur OSX 10.10 (le makefile est à revoir). Je regarde tout ça dès que possible.Un autre intérêt c'est qu'on peut passer en 64 bits! A + | |
GreG | 26-Jan-2015/22:48:53+1:00 |
Par contre il n'y a toujours pas de View pour OSX, ce sera à nous de le faire! Windows et Linux pour le moment... | |
Login required to Post. |