morefigs / pymba

Python wrapper for Allied Vision's Vimba C API
MIT License
105 stars 84 forks source link

Porting to python 3? #19

Closed ecx2093 closed 5 years ago

ecx2093 commented 8 years ago

Could anyone make this compatible with python 3? I think it would be useful for most users, including myself.

morefigs commented 8 years ago

Feel free to do so :)

Gloweye commented 8 years ago

I very much agree to this, and I could put in some time. Any pointers as what needs to be done? I've never done something like this before.

morefigs commented 8 years ago

There's probably not much to it in this case as the code is quite repetitive and predictable - it's generally just ctypes function definitions and function calls to C functions, and afaik ctypes hasn't changed much. There might be . It'd be worth simply trying it and seeing how it breaks.

Gloweye commented 8 years ago

vimba.py has two print statements that need parenthesis. Lines 77 and 115.

Also, installing Vimba (1.4) to default location puts the DLL at another location then where the script is expecting it. (on windows 64-bit, using python 3.4). So the path in vimbadll should be:

C:\Program Files\Allied Vision\Vimba_1.%i\VimbaC\Bin\Win%i\VimbaC.dll

instead of

C:\Program Files\Allied Vision Technologies\AVTVimba_1.%i\VimbaC\Bin\Win%i\VimbaC.dll

From the python interpreter, "from pymba import *" also gives an error stating vimba doesn't exist, regardless of administrator privileges. Running__init__.py directly does work(resolving the two issues above). Any clues as what might be going on there?

Gloweye commented 8 years ago

Hmmm..if I run python from the local spot of the __init__.py, it does work, and it passes the test noted on this project's front page as "without context manager".

Don't know enough about what I'm doing to help resolve that ATM though - probably has something to do with python's magical import statements, which changed at 3.3 release. I hope this information is useful for making stuff work with the newer versions?

mabl commented 8 years ago

Pull request #22 adds basic Python 3 support. I'd be glad if you gave it a try.

Gloweye commented 8 years ago

After changing the DLL location(possible to check for both? Dunno if it's worth the effort, but otherwise a note on the front page might be useful), I got an AttributeError: 'module' object has no attribute 'vimbastructure', located at vimba.py at line 3.

mabl commented 8 years ago

Hmm strange. This is with my python3 branch? Which python version exactly. Can you post a full backtrace?

Gloweye commented 8 years ago

Yeah, I uninstalled, redownloaded through the commit, and reinstalled that version. It's gotta be the right one, verified by opening vimba.py and seeing those print statements gone.

But it's kind of weird - I can't seem to reproduce it now in order to get that copy-paste. All seems to work now. Best to disregard this for the time being?

It also passes the front page test now, run from any location.

mabl commented 8 years ago

I guess so. Let me know how the rest of that port turns out.

Gloweye commented 8 years ago

Sure. It's a week until I get my hands on the actual camera, and I'll be sure to check back if there's something weird happening - or to report success. Thanks in any case.

ecx2093 commented 8 years ago

Hi and thanks for working on this! I downloaded mabl's branch and installed it on my windows system. pymba can find vimba version 1.4.1 (using vimba.getVersion), but some of the examples from morefig's readme fail. It seems like getFeatureNames is not working properly? Here is an example:

Traceback (most recent call last): File "vimba_test.py", line 10, in if system.GeVTLIsPresent: File "C:\Users~\Anaconda3\lib\site-packages\pymba-0.1-py3.5.egg\pymba\vimbaobject.py", line 36, in getattr if attr in self.getFeatureNames(): File "C:\Users~\Anaconda3\lib\site-packages\pymba-0.1-py3.5.egg\pymba\vimbaobject.py", line 110, in getFeatureNames return list(featInfo.name.decode() for featInfo in self._getFeatureInfos()) File "C:\Users~\Anaconda3\lib\site-packages\pymba-0.1-py3.5.egg\pymba\vimbaobject.py", line 82, in _getFeatureInfos raise VimbaException(errorCode) pymba.vimbaexception.VimbaException: More data was returned in a string/list than space was provided.

I am happy to try out any suggestions.

mabl commented 8 years ago

Hmm interesting. Does this maybe also happen with the original master in Python 2?

mabl commented 8 years ago

Ah this bug #21. Could you change line 77 from 0 to 1?

https://github.com/mabl/pymba/blob/master/pymba/vimbaobject.py#L77

ecx2093 commented 8 years ago

Hm that doesn't seem to work. The same error is returned if line 77 is between 0-15. For larger values, python crashes. I tried the trick from @nikitchm by changing numFeatures = 1000 but I still get the same error:

raise VimbaException(errorCode) a.vimbaexception.VimbaException: More data was returned in a string/list than space was provided.

Commenting out the error (line 81-82) results in the following:

File "C:\Users~\Anaconda3\lib\site-packages\pymba-0.1-py3.5.egg\pymba\vimbaobject.py", line 89, in _getFeatureInf os featureInfoArray = (structs.VimbaFeatureInfo * numFeatures)() OverflowError: The 'length' attribute is too large

mabl commented 8 years ago

Strange... But I am still not at vimba 1.4. I guess its better solved in the master branch. Until then, I'd recommend using vimba 1.3

nikitchm commented 8 years ago

I understand that you have tried to follow the same recipe hack that worked for me, but, to be sure there is no mistake, below is the modified version of _getFeatureInfos(self) method from vimbaobject.py:

`def _getFeatureInfos(self): """ Gets feature info of all available features. Will cause error if object/camera is not opened.

:returns: list -- feature info for available features.
"""
# check it's populated as can't populate it in __init__
if self._featureInfos is None:
    # args
    dummyFeatureInfo = structs.VimbaFeatureInfo()
    numFound = c_uint32(-1)

    # call once to get number of available features
    # Vimba DLL will return an error code
    errorCode = VimbaDLL.featuresList(self._handle,
                                      byref(dummyFeatureInfo),
                                      0,
                                      byref(numFound),
                                      sizeof(dummyFeatureInfo))
    if errorCode != 0:
        pass                                                  #!!! modified (commented the line below)
        # raise VimbaException(errorCode)

    # number of features specified by Vimba
    numFeatures = numFound.value
    numFeaturesFix =  1000                                     #!!! modified. Added this line
    print("numFeatures returned by the .dll: {}. Forcing maximum number of feature to be equal {}".format(numFeatures, numFeaturesFix))    #!!! modified. Added this line
    numFeatures = numFeaturesFix                              #!!! modified. Added this line

    # args
    featureInfoArray = (structs.VimbaFeatureInfo * numFeatures)()

    # call again to get the features
    # Vimba DLL will return an error code
    errorCode = VimbaDLL.featuresList(self._handle,
                                      featureInfoArray,
                                      numFeatures,
                                      byref(numFound),
                                      sizeof(dummyFeatureInfo))
    if errorCode != 0:
        raise VimbaException(errorCode)

    # self._featureInfos = list(
    #     featInfo for featInfo in featureInfoArray)        #!!! modified. Commented and added the following two lines
    self._featureInfos = list(featInfo for featInfo in featureInfoArray if featInfo.name is not None)
    print("Number of features detected and left in the list: {}".format(len(self._featureInfos)))
return self._featureInfos

`

morefigs commented 8 years ago

Yes that seems to be a bug that has crept up in version 1.4. The first call of VimbaDLL.featuresList is simply to get the number of features, so may be avoidable altogether. Unfortunately I can't really comment on a fix as I don't have a camera to test with. However it's fairly safe to say this has nothing to do with the Python version.

Gloweye commented 8 years ago

It seems like the most recent master once again has the parenthesis missing in the print commands. Just a heads up.

mabl commented 8 years ago

Yes it does, since this code has not been merged yet :-)

Gloweye commented 8 years ago

Trying now with Python 3.5 and Vimba 1.4. There's quite some weird stuff going on. There's a couple of functions that work completely fine. A number of other cause python crashes in a variance of about 20-80% of the time. They're never 1 on 1 reproducible. A couple of perfect citizens(never crash):

vimba.getSystem()
system.runFeatureCommand(b"GeVDiscoveryAllOnce")#only when using bytestring
vimba.getCamera(b"<cameraref>")
camera.cameraIdString
frame.announceFrame()
camera.startCapture()
frame.queueFrameCapture()
camera.runFeatureCommand('AcquisitionStart')#Doesn't seem to need bytestring...
camera.runFeatureCommand('AcquisitionStop')#Doesn't need bytestring either.
camera.endCapture()
cameraref.revokeAllFrames()

A couple of offenders:

system.GeVTLIsPresent       #medium crash chance
camera.getFeatureNames() #high crash chance
camera.getFrame()               #Medium/low crash chance
frame.waitFrameCapture()    #Always times out, also high crash chance.
frame.getBufferByteData()    #very high crash chance.

When crashing it seems to have something to do with the calls to the DLL. Crossreferencing the official C API from allied vision with vimbadll.py didn't let anything jump out - it all looks like it should work fine to me, but I never did any wrapping myself.

Also, it seems that some calls aren't as blocking as I'd expect - I often see the results of some of my print statements from after the guilty line. My creeping suspicion is that the non-blocking behaviour may cause crashes(because of missing data or the C trying to access it while python is doing the same). I don't know if all this makes much sense, but I though I'd throw it out here.

For the sake of clarity, I'm using the Python 3 branch, manually carrying the 999 change in GetFeatureNames(or info's, or whatever). I did litter them with some print statements, but no other changes were made.

morefigs commented 8 years ago

Strange that it crashes sometimes. I take it your camera is fine otherwise?

Gloweye commented 8 years ago

Yeah, using Vimba itself appears to work exactly as expected. Camera is brand new.

I'm first gonna try and use older versions of Vimba and it's DLL and see if that works. Otherwise, maybe older versions of python, tho there'd be a lot more code I need to rebuild and I can't for the life of me name a possible cause in the python coding.

Gloweye commented 8 years ago

Hm. I seem unable to find older version's DLL's on the internet. Any chance you could mail me yours?

I did try Vimba 2.0 as well, but that doesn't work either.

Traceback (most recent call last):
  <Module reference>
vimba.startup()
  File "C:\Users\me\Anaconda3\lib\site-packages\pymba\vimba.py", line 250, in startup
    raise VimbaException(errorCode)
pymba.vimbaexception.VimbaException: No transport layers were found.

may be a problem for another time though. Or even one on my end.

Gloweye commented 8 years ago

I did find and activate the Vimba DLL's own logs. When the "timeout" occurs, this is the last part:

-snip- 2016-03-16 10:26:40.244: VmbFeatureInfoQuery called 2016-03-16 10:26:40.244: VmbFeatureInfoQuery: Input Parameter handle = Handle 0x000000000000068D 2016-03-16 10:26:40.244: VmbFeatureInfoQuery: Input Parameter name = Pointer 0x00000000042B20B0 to Char (Pix...) 2016-03-16 10:26:40.244: VmbFeatureInfoQuery: Input Parameter pFeatureInfo = Pointer 0x0000000005B90A70 2016-03-16 10:26:40.244: VmbFeatureInfoQuery: Input Parameter sizeofFeatureInfo = UInt32 96 (0x00000060) 2016-03-16 10:26:40.244: VmbFeatureInfoQuery returned Int32 0 (0x00000000) 2016-03-16 10:26:40.244: VmbFeatureInfoQuery: Output Parameter pFeatureInfo = Pointer 0x0000000005B90A70 2016-03-16 10:26:40.244: VmbFeatureEnumGet called 2016-03-16 10:26:40.244: VmbFeatureEnumGet: Input Parameter handle = Handle 0x000000000000068D 2016-03-16 10:26:40.244: VmbFeatureEnumGet: Input Parameter nam -abrupt end to the log. Not even a newline.-

I call it a timeout, because errorCode -12 is returned from frame.waitFrameCapture(). However, I set it to 10 seconds and it looks like there's something deeper down that doesn't work/return. Program always crashes as a result, tho there's some print statements getting through that are below the frame command in python.

Gloweye commented 8 years ago

I don't know if it's still suitible for Python 3 as thread...

Anyway, using the DLL's from Vimba 1.3 seems to fix the crashes far as far as I can see(I got them from AT technical support). I'm still getting timeouts for every attempted frame tho, using the code on the front page. I'll post again if I know more.

Gloweye commented 8 years ago

Everything seems to be working. To fix the timeout problems, I needed to implement a time.sleep(0.2) between acquisition start and stop(not noted on the front page example. May be a good idea?)

I don't know if there's the plans to make it compatible with later vimba DLL's, but otherwise it might be a good idea to package the one from 1.3 with Pymba, to ensure compatibility, if copyright permits.

I seem to be getting a scrambled image - resolved withndarray = ndarray.reshape(ndarray.shape[1],ndarray.shape[0]).T

basically reshaping it, then transposing it. after that the image seems to be as expected(aside from possible mirrorings - still investigating those)

So, as far as I can say with my testing, the current Python 3 branch seems to be working perfectly fine.

morefigs commented 8 years ago

@Gloweye could you please try Vimba > 1.3 again? Would be interesting to see if your random crashes have been fixed by the latest commit, see https://github.com/morefigs/pymba/pull/27 for details.

Gloweye commented 8 years ago

Python 3.5 seems to work with the Python 3 compatibility branch and this manual patch without further issues. Tested with both Vimba 1.4 and 2.0.

morefigs commented 5 years ago

master branch is now fully Python 3 compatible.