简体   繁体   English

如何在python中使用opencv从sftp位置读取视频文件

[英]How to read video file from sftp location using opencv in python

I am facing issue in reading file from sftp location using opencv lib. 我在使用opencv lib从sftp位置读取文件时遇到问题。 Can you tell me how to read file from sftp location or sftp file object. 您能告诉我如何从sftp位置或sftp文件对象读取文件。 If can you tell me read large file directly to opencv lib then it's good things. 如果您能告诉我直接将大文件读取到opencv lib,那就好了。

import paramiko
import cv2
import numpy as np

client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect("IPADDRESS", port=22, username='USERNAME', password='PASSWORD')
t = client.get_transport()
sftp = paramiko.SFTPClient.from_transport(t)
sftp.chdir("/home/bizviz/devanshu_copy")

obj = sftp.open("SampleVideo_1280x720_1mb.mp4")

cap = cv2.VideoCapture.open(obj)

while True:
    _,frame = cap.read()
    print(frame)
    cv2.imshow('res', frame)
    key = cv2.waitKey(1)
    if key == 27:
        break

cap.release()
cv2.destroyAllWindows()

using just Paramiko you'll need to copy the file to the local filesystem and then use that local file for cv2. 仅使用Paramiko,您需要将文件复制到本地文件系统,然后将该本地文件用于cv2。

cv2 doesn't accept this method of passing a file. cv2不接受这种传递文件的方法。

Of course, python has libraries for everything, so I think using fs.sshfs , which is an extension on pyfilesystem2 to include SFTP, should do the trick. 当然,python具有用于所有内容的库,因此我认为使用fs.sshfs应该可以解决问题, fs.sshfspyfilesystem2的扩展,其中包括SFTP。 NOTE HERE, this doesn't actually play nice with opencv-python . 注意这里,这实际上与opencv-python不能很好地配合使用。


EDIT1: 编辑1:

from the docs here you can see which ways you can pass a file to VideoCapture.Open(). 这里文档中,您可以看到将文件传递给VideoCapture.Open()的方式。 在此处输入图片说明

Editing the code to copy the file locally and then pass the local file to openCV works correctly. 编辑代码以在本地复制文件,然后将本地文件传递给openCV可以正常工作。

sftp.get('file.mp4', 'file.mp4')
sftp.close() # Also, close the sftp connection

cap = cv2.VideoCapture.open('file.mp4')

EDIT2: 编辑2:

So, mounting the SFTP filesystem to the local filesystem using ssfhs works. 因此,使用ssfhs将SFTP文件系统安装到本地文件系统是ssfhs Best way would be to mount the SFTP on the OS level using the tested methods for this. 最好的方法是使用经过测试的方法在操作系统级别挂载SFTP。 Below is sample python code to do everything in python, but note that this assumes ssfhs can connect correctly to the SFTP host from commandline. 以下是在Python中执行所有操作的示例python代码,但请注意,这假设ssfhs可以ssfhs正确连接到SFTP主机。 I'm not explaining that part here as there are excellent different tutorials for that. 我没有在这里解释这一部分,因为有很多出色的 教程

Note that this only contains some basic error checking so I advise to make sure you catch any errors that might pop up. 请注意,这仅包含一些基本的错误检查,因此我建议确保您捕获可能弹出的任何错误。 This is proof of concept. 这是概念的证明。

import cv2
import os
import subprocess


g_remoteuser = 'USERNAME'
g_remotepassword = 'PASSWORD'
g_remotehost = 'HOSTIP'
g_remotepath = '/home/{remoteuser}/files'.format(remoteuser=g_remoteuser)
g_localuser = 'LOCAL_MACHINE_LINUX_USERNAME'
g_localmntpath = '/home/{localuser}/mnt/remotehost/'.format(localuser=g_localuser)
g_filename = 'file.mp4'


def check_if_path_exists(path):
    # check if the path exists, create the path if it doesn't
    if not os.path.exists(path):
        os.makedirs(path)


def mount(remoteuser, remotehost, remotepath, remotepassword, localmntpath):
    check_if_path_exists(localmntpath)
    if not check_if_mounted(localmntpath):
        subprocess.call([
            '''echo "{remotepassword}" | sshfs {remoteuser}@{remotehost}:{remotepath} {localmntpath} \
             -o password_stdin -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o auto_unmount -o allow_other'''.format(
                remoteuser=remoteuser,
                remotehost=remotehost,
                remotepath=remotepath,
                localmntpath=localmntpath,
                remotepassword=remotepassword
            )], shell=True)


def unmount(path):
    try:
        subprocess.call(['sudo umount -l {path}'.format(path=path)], shell=True)
    except Exception as e:
        print(e)


def check_if_mounted(path):
    # check if there's actually files. Hacky way to check if the remote host is already mounted.
    # will of course fail if there's no files in the remotehost
    from os import walk
    f = []
    for (dirpath, dirnames, filenames) in walk(path):
        f.extend(filenames)
        f.extend(dirnames)
        if dirnames or filenames or f:
            return True
        break
    return False


if check_if_mounted(g_localmntpath):
    unmount(g_localmntpath)

mount(g_remoteuser, g_remotehost, g_remotepath, g_remotepassword, g_localmntpath)


cap = cv2.VideoCapture()
cap.open(g_localmntpath + g_filename)


while True:
    _, frame = cap.read()
    print(frame)
    cv2.imshow('res', frame)
    key = cv2.waitKey(1)
    if key == 27:
        break

cap.release()
cv2.destroyAllWindows()
unmount(g_localmntpath)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM