I really appreciate using Pandore library (https://clouard.users.greyc.fr/Pandore/) which provides a lot of useful image processing operators. In many case when processing images, you have to apply successive operators: An image processing application is a chain of operators and Pandore offers very efficient operators. The library is 100% pure C++ code and can't be easily binded to Red. But we have a solution with red call instruction which can be used to execute a shell process to run another process or program.
Installing Pandore
Go to Pandore website and download the lib which is optimized for Unix, Linux, Windows and macOS.
The complete installation needs a C++ compiler which is required and Qt (version >= 4.0.0) or X11 and Motif for visualization operation (www.trolltech.com).Without these API, operators 'pvisu' and 'pdraw' are not available. However, the rest of the operators works without Qt (or X11).
Then unpack the distribution on your computer.
Installation is straightforward:
- ./configure
- make
- make install
- make clean
Using Pandore with Red
The idea is now to call the operators from Red program with call. This is really simple. All operators are in pandore_6.6.7/bin directory and your red code must point to this directory
panhome: "Your access to/pandore_6.6.7"
change-dir to-file panhome
Then just use call operator
call/output "bin/pversion" statusThe pversion operator can be used to test if the pandore lib is correctly installed. Here we use wait/output in order to redirect stdout to a string and get the result of the operator: SUCCESS or FAILURE. When using other operators which process image don't forget to use call/wait to run the operator and wait for exit.
Pandore creates a specific image format (.pan) and thus you code must convert red image to pandore image with pany2pan operator.
In the code example we call then the pthresholding operator which build the output image with the pixels of the input image that have a value greater or equal than low or lower or equal than high provided by sliders. Other values are set to 0. Lastly we call ppan2jpeg operator which transform the filtered image to jpg image.
Code sample
Red [
Title: "Pandore test"
Author: "Francois Jouen"
File: %threshold2.red
Needs: 'View
]
status: ""
isFile: false
srcImg: none
f: ""
lowT: 0
highT: 255
prog: make string! ""
dSize: 256
gsize: as-pair dSize dSize
sldSize: as-pair ((dSize * 2) - 100) 16
; update according to you OS and pandore directory
panhome: "/Libraries/pandore_6.6.7"
change-dir to-file panhome
; is pandore installed?
call/output "bin/pversion" status
; Converts red loaded image to pandore image
red2pan: func [img [file!] return: [string!]] [
fName: ""
fName: form second split-path img
fileName: copy/part fName (length? fName) - 4 ;removes .ext
append fileName ".pan"
prog: copy "bin/pany2pan "
append append append prog to-string img " /tmp/" fileName
call/wait prog
call/output "bin/pstatus" status
fileName ; returns filename
]
; Pandore thresholding
{pthresholding builds the output image with the pixels of the input image
that have a value greater or equal than low or lower or equal than high. Other values are set to 0}
thresholdPan: func [fn [string!] t1 [integer!] t2 [integer!]] [
prog: copy "bin/pthresholding "
append append append prog form t1 " " form t2
append prog " /tmp/" ; default dir for storing pandore images
append append prog fn " /tmp/result.pan"
call/wait prog
call/output "bin/pstatus" status
]
;Converts to jpg
pan2JPG: does [
prog: copy "bin/ppan2jpeg 1.0"
append append prog " /tmp/result.pan" " /tmp/result.jpg"
call/wait prog
call/output "bin/pstatus" status
]
; Removes all pandore images in /tmp/ directory
removePanImg: does [call "rm /tmp/*.pan"
call "rm /tmp/*.jpg"
call "rm /tmp/pand*"
sb2/text: "All pandore images removed"]
; Loads red image
loadImage: does [
isFile: false
clear sb2/text
canvas2/image: none
tmpFile: request-file
if not none? tmpFile [
srcImg: load tmpFile
canvas/image: srcImg
isFile: true
sb2/text: "Red Image loaded"
]
]
; Processes image
process: does [
resImg: %/tmp/result.jpg
sb2/text: copy "Shows filtered pan image: "
thresholdPan f lowT highT
pan2JPG
append sb2/text status
if exists? resImg [canvas2/image: load resImg]
]
; ***************** Test Program ****************************
view win: layout [
title "Pandore Thresholding"
button 100 "Load Image" [loadImage f: red2pan tmpFile process]
button 70 "Quit" [removePanImg Quit]
return
text 50 "Low"
sl1: slider sldSize [lowT: to-integer face/data * 255
lowsb/text: form lowT
if isFile [process]]
lowsb: field 40 "0"
return
text 50 "High"
sl2: slider sldSize [highT: to-integer face/data * 255
highsb/text: form highT
if isFile [process]]
highsb: field 40 "255"
return
text dSize "Source"
text dSize "Result"
return
canvas: base gsize black
canvas2: base gsize black
return
sb1: field dSize
sb2: field dSize
do [sb1/text: status sl1/data: lowT / 255.0 sl2/data: highT / 255.0]
]
Result
Red and Pandore: a great association !
Aucun commentaire:
Enregistrer un commentaire