kerberos-io / machinery

(DEPRECATED) An open source image processing framework, which uses your USB-, IP- or RPi-camera to recognize events (e.g. motion).
https://www.kerberos.io
490 stars 104 forks source link

Image lock #74

Closed nragon closed 7 years ago

nragon commented 7 years ago

Hi,

Image is getting locked until cv::Mat m_image is out of scope. It's impossible to use the capture(open in rb mode) after IoDisk. Maybe you can deep copy m_image and save its copy, just guessing.

Thanks

cedricve commented 7 years ago

@nragon can you reference the code block?

nragon commented 7 years ago

I made a pull request with this issue. It's an idea which might do. But I'm not able to test it yet. I believe this issue happens because IoDisk uses imwrite to save to disk but because Image is still in scope when saving the next Io's, the reference to cv::Mat which was used to save the image is locking that file.

cedricve commented 7 years ago

I don't see any issue with this.. Can you explain why you think this is blocking? Though please create a pull request, after you've tested it properly.

nragon commented 7 years ago

Sorry about the pull, but I didn't have the time to set the environment to test. After using IoDisk I'm using IoScript. Inside i'm runnig run.sh and calling a python script which tries to open the image sent as stdin.

with open(image, 'rb') as f:
        data = f.read()

Can you confirm this snippet works in your side? I can execute the script standalone but not through kerberosio.

Thanks

cedricve commented 7 years ago

Thanks for clarification, did you tried to log to a file?

nragon commented 7 years ago

Yes, everything happens correctly on kerberosio side (Motion detected -> IoDisk -> IoScript) until it tries to open the file in the script. I've log untill open() and inside it but with not success. In order for you to test, if possible. run.sh:

#!/bin/bash

# -------------------------------------------
# This is an example script which illustrates
# how to use the Script IO device.
#

# --------------------------------------
# The first parameter is the JSON object
#
# e.g. {"regionCoordinates":[308,250,346,329],"numberOfChanges":194,"timestamp":"1486049622","microseconds":"6-161868","token":344,"pathToImage":"1486049622_6-161868_frontdoor_308-250-346-329_194_344.jpg","instanceName":"frontdoor"}

scriptDir=`dirname "$0"`
scriptDir=`cd "${scriptDir}"; pwd`

JSON=$1

# -------------------------------------------
# You can use python to parse the JSON object
# and get the required fields

name=$(echo $JSON | python -c "import sys, json; print json.load(sys.stdin)['instanceName']")
coordinates=$(echo $JSON | python -c "import sys, json; print json.load(sys.stdin)['regionCoordinates']")
changes=$(echo $JSON | pythfon -c "import sys, json; print json.load(sys.stdin)['numberOfChanges']")
image=$(echo $JSON | python -c "import sys, json; print json.load(sys.stdin)['pathToImage']")

python "${scriptDir}/kerberos.py" $image

On python script just try to open the captured image:

import sys

capture = sys.argv[1]
with open(capture , 'rb') as f:
        data = f.read()
        print "Works"

I don't have the scripts with me atm, if this doesn't work i'll post them later. Thanks

cedricve commented 7 years ago

Well you should add the directory path in front of $image. By default only the name of the image is in the json object.

{ "regionCoordinates":[308,250,346,329], "numberOfChanges":194, "timestamp":"1486049622", "microseconds":"6-161868", "token":344, "pathToImage":"1486049622_6-161868_frontdoor_308-250-346-329_194_344.jpg", "instanceName":"frontdoor" }

nragon commented 7 years ago

Ok, pathToImage mistaken me. Closing pull. But it would be better to send full path.

cedricve commented 7 years ago

Well not really because one can choose to access the image over URL (http://192.168.0.11/image.jpg) or over filesystem (/etc/opt/kerberosio/capture/image.jpg).

nragon commented 7 years ago

Yes, true, either ways should have the prefix to image. Configurations should happen on kerberosio and not hardcoded in scripts, imo.

cedricve commented 7 years ago

What would you suggest @nragon ?

nragon commented 7 years ago

Well, considering a user might want to send the image url thought script or access it directly it's better to add both options as attributes.

{
"regionCoordinates":[308,250,346,329],
"numberOfChanges":194,
"timestamp":"1486049622",
"microseconds":"6-161868",
"token":344,
"pathToImage": "/etc/opt/kerberosio/capture",
"urlToImage": "http://192.168.0.11",
"imageName":"1486049622_6-161868_frontdoor_308-250-346-329_194_344.jpg",
"instanceName":"frontdoor"
}
cedricve commented 7 years ago

That could work for the filesystem, but not for the url. The machinery can run without the web interface, and doesn't have any knowledge (dependency) with the web interface.

nragon commented 7 years ago

urlToImage can work with some function to access local ip. Agree? pathToImage should be there because you configure it on IoDisk

cedricve commented 7 years ago

Yeah you got a point, but when working with docker containers this will not work. I think it would be good to start with the pathToImage. Thanks for your feedback!

nragon commented 7 years ago

No problem :)