Opencv Data

Hello, could someone explain me, how i could get OpenCvData to my Python Script, like the size of the Box of an detected Object. I tried around with the add.listener think and some oder combinations, but couldn't get the Data to be retreived in the Script so i could use it (for exemple simple printing it).
Im sorry for all the questions i am asking right now, but i am not familiar with such Data Structure and it's difficult for me to read the javadoc thing to get stuff going.
Thanks for your help.

GroG's picture

Added example to Service page

Added example to Service page script:

http://myrobotlab.org/service/OpenCV


#file : service/OpenCV.py edit raw
from org.myrobotlab.image import Util
# start a opencv service

opencv = Runtime.start("opencv","OpenCV")
#gui.setActiveTab("opencv")

# add python as a listener to OpenCV data
# this tells the framework - whenever opencv.publishOpenCVData is invoked
# python.onOpenCVData will get called
python = Runtime.start("python","Python")
python.subscribe("opencv", "publishOpenCVData")


# call back - all data from opencv will come back to 
# this method
def onOpenCVData(data):
  # check for a bounding box
  if data.getBoundingBoxArray() != None:
    for box in data.getBoundingBoxArray():
      print("bounding box", box.x, box.y, box.width, box.height)

# to capture from an image on the file system
# opencv.captureFromImageFile("C:\Users\grperry\Desktop\mars.jpg")

# not for you, it's for test
if ('virtual' in globals() and virtual):
  opencv.setMinDelay(500)
  opencv.setFrameGrabberType("org.bytedeco.javacv.FFmpegFrameGrabber")
  opencv.setInputSource("file")
  opencv.setInputFileName(Util.getRessourceDir()+"OpenCV/testData/monkeyFace.mp4")

opencv.capture()

#### LKOpticalTrack ####################
# experiment with Lucas Kanade optical flow/tracking
# adds the filter and one tracking point

opencv.addFilter("LKOpticalTrack")
opencv.setDisplayFilter("LKOpticalTrack")
# attempt to set a sample point in the middle 
# of the video stream - you can 
opencv.invokeFilterMethod("LKOpticalTrack","samplePoint", 0.5, 0.5)
sleep(4)
opencv.removeFilters()

opencv.addFilter("FaceDetect")
opencv.setDisplayFilter("FaceDetect")
# attempt to set a sample point in the middle 
# of the video stream - you can 

sleep(4)
opencv.removeFilters()
 

#### PyramidDown ####################
# scale the view down - faster since updating the screen is 
# relatively slow
opencv.addFilter("PyramidDown")
opencv.setDisplayFilter("PyramidDown")
sleep(4)
# adding a second pyramid down filter - we need
# a unique name - so we'll call it PyramidDown2
opencv.addFilter("PyramidDown2","PyramidDown")
opencv.setDisplayFilter("PyramidDown2")
sleep(4)
opencv.removeFilters()


#### Canny ########################
# adding a canny filter
opencv.addFilter("Canny")
opencv.setDisplayFilter("Canny")
sleep(4)
canny = opencv.getFilter("Canny") 
# changing parameters
canny.apertureSize = 3
canny.lowThreshold = 10.0
canny.highThreshold = 200.0

sleep(2)

canny.apertureSize = 5
canny.lowThreshold = 10.0
canny.highThreshold = 100.0

sleep(4)
opencv.removeFilters()
opencv.stopCapture()

Kakadu31's picture

Thank you very much

Thank you for the quick and easy response. I wrote something similar, but didnt put "data" in the brackets at the input function for the message. =)

It would be very awesome if someone could explain me, why this is needed in this case, or when you have to pass something similiar to a function.
 

EDIT: If someone wants to do this with the opencv created by the tracking service, use:

opencv = tracker.getOpenCV()

GroG's picture

Synchronous vs Asynchronous

Its the same data, but MyRobotLab allows you to interact with it Synchronously or Asynchronously.

Typically - Asynchronous is more like life :)  Events happen, and we get notified versus polling and waiting for return data.

Many services produce data - and we don't know what schedule they are on, or when it will happen .. rather than poll data like this:

while (running) {
  data = tracker.getOpenCV()
  ...do something...
}

we simply let the Service produce the data and allow it to call our function.  
But it takes 2 parts:

1 part to setup the "route"

opencv.addListener("publishOpenCVData", "python","onOpenCVData")

this tells the OpenCV service when it's publishOpenCVData method is called route the returned data to python.onOpenCV(data)

def onOpenCVData(data):
  ...do something...

 

 

Kakadu31's picture

Script structure

Ok good to know, but it leads me to another question, if i start programming for my robot, do i have a loop function where i can write for example the if commands, to tell what to do in what case, or do i put all this decisionmaking in functions like the onOpencvData we used now for each service? It seems more simple to do it 'the arduino-loop' way?

GroG's picture

Its completely up to you.

Its completely up to you.  

Your robot is a Finite State Machine .. like pretty much everything in the universe...

Most living things don't have a single loop :)

But a single loop does make programming easier to get started.... and you have to start somewhere