【问题标题】:Python: how to capture image from webcam on click using OpenCVPython:如何使用 OpenCV 在单击时从网络摄像头捕获图像
【发布时间】:2016-04-07 21:46:14
【问题描述】:

我想使用 OpenCV 从我的网络摄像头捕获并保存一些图像。这是我目前的代码:

import cv2

camera = cv2.VideoCapture(0)
for i in range(10):
    return_value, image = camera.read()
    cv2.imwrite('opencv'+str(i)+'.png', image)
del(camera)

这样做的问题是我不知道图像是什么时候拍摄的,所以很多图像最终变得模糊。我的问题是:有没有办法通过点击键盘键来拍摄图像?

还有没有更好的方法来拍摄多张图像,而不是范围?

【问题讨论】:

    标签: python python-2.7 opencv


    【解决方案1】:

    我对 open cv 不太熟悉,但是如果您希望在按下某个键时调用 for 循环中的代码,您可以使用 while 循环和 raw_input 以及一个条件来防止循环永远执行

    import cv2
    
    camera = cv2.VideoCapture(0)
    i = 0
    while i < 10:
        raw_input('Press Enter to capture')
        return_value, image = camera.read()
        cv2.imwrite('opencv'+str(i)+'.png', image)
        i += 1
    del(camera)
    

    【讨论】:

    • 如果您使用的是 Python3,请将“raw_input()”函数更改为“input()”函数。
    【解决方案2】:

    这是一个简单的程序,它在cv2.namedWindow 中显示摄像头信息,并在您点击SPACE 时拍摄快照。如果您点击ESC,它也会退出。

    import cv2
    
    cam = cv2.VideoCapture(0)
    
    cv2.namedWindow("test")
    
    img_counter = 0
    
    while True:
        ret, frame = cam.read()
        if not ret:
            print("failed to grab frame")
            break
        cv2.imshow("test", frame)
    
        k = cv2.waitKey(1)
        if k%256 == 27:
            # ESC pressed
            print("Escape hit, closing...")
            break
        elif k%256 == 32:
            # SPACE pressed
            img_name = "opencv_frame_{}.png".format(img_counter)
            cv2.imwrite(img_name, frame)
            print("{} written!".format(img_name))
            img_counter += 1
    
    cam.release()
    
    cv2.destroyAllWindows()
    

    我认为这应该在很大程度上回答您的问题。如果有哪一行你不明白,请告诉我,我会添加 cmets。

    如果您需要在每次按下SPACE 键时抓取多张图像,您将需要一个内部循环,或者可能只是制作一个抓取一定数量图像的函数。

    请注意,关键事件来自cv2.namedWindow,因此它必须具有焦点。

    【讨论】:

    • 如果您包括人们可以更改存储这些图像的位置的行,那将是完整的。无论如何,伟大的作品
    【解决方案3】:

    分解您的代码示例(说明在代码行下方。)

    import cv2
    

    导入 openCV 以供使用

    camera = cv2.VideoCapture(0)
    

    使用连接到计算机的相机列表中的第一个相机创建一个名为相机的对象,类型为 openCV 视频捕获。

    for i in range(10):
    

    告诉程序循环以下缩进代码 10 次

        return_value, image = camera.read()
    

    使用它的 read 方法从相机对象中读取值。 它有 2 个值 将 2 个数据值保存到两个名为“return_value”和“image”的临时变量中

        cv2.imwrite('opencv'+str(i)+'.png', image)
    

    使用 openCV 方法 imwrite(将图像写入磁盘)并使用临时数据变量中的数据写入图像

    更少的缩进意味着循环现在已经结束...

    del(camera)
    

    删除 camrea 对象,我们不再需要它。

    您可以通过多种方式满足您的要求,一种方法是将 for 循环替换为 while 循环(永远运行,而不是 10 次),然后等待按键(就像 danidee 回答的那样,而我正在打字)

    或者创建一个更邪恶的服务,它隐藏在后台并在每次有人按下键盘时捕获图像......

    【讨论】:

      【解决方案4】:

      这是一个使用笔记本电脑默认摄像头捕捉图像的简单程序。我希望这对所有人来说都是非常简单的方法。

      import cv2
      
      # 1.creating a video object
      video = cv2.VideoCapture(0) 
      # 2. Variable
      a = 0
      # 3. While loop
      while True:
          a = a + 1
          # 4.Create a frame object
          check, frame = video.read()
          # Converting to grayscale
          #gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
          # 5.show the frame!
          cv2.imshow("Capturing",frame)
          # 6.for playing 
          key = cv2.waitKey(1)
          if key == ord('q'):
              break
      # 7. image saving
      showPic = cv2.imwrite("filename.jpg",frame)
      print(showPic)
      # 8. shutdown the camera
      video.release()
      cv2.destroyAllWindows 
      

      可以看我的github代码here

      【讨论】:

      • 谢谢。 @Robot,你现在可以检查了。
      【解决方案5】:

      这是一个使用默认相机捕捉图像的简单程序。 此外,它可以检测人脸

      import cv2
      import sys
      import logging as log
      import datetime as dt
      from time import sleep
      
      cascPath = "haarcascade_frontalface_default.xml"
      faceCascade = cv2.CascadeClassifier(cascPath)
      log.basicConfig(filename='webcam.log',level=log.INFO)
      
      video_capture = cv2.VideoCapture(0)
      anterior = 0
      
      while True:
          if not video_capture.isOpened():
              print('Unable to load camera.')
              sleep(5)
              pass
      
          # Capture frame-by-frame
          ret, frame = video_capture.read()
      
          gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
      
          faces = faceCascade.detectMultiScale(
              gray,
              scaleFactor=1.1,
              minNeighbors=5,
              minSize=(30, 30)
          )
      
          # Draw a rectangle around the faces
          for (x, y, w, h) in faces:
              cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)
      
          if anterior != len(faces):
              anterior = len(faces)
              log.info("faces: "+str(len(faces))+" at "+str(dt.datetime.now()))
      
      
          # Display the resulting frame
          cv2.imshow('Video', frame)
      
          if cv2.waitKey(1) & 0xFF == ord('s'): 
      
              check, frame = video_capture.read()
              cv2.imshow("Capturing", frame)
              cv2.imwrite(filename='saved_img.jpg', img=frame)
              video_capture.release()
              img_new = cv2.imread('saved_img.jpg', cv2.IMREAD_GRAYSCALE)
              img_new = cv2.imshow("Captured Image", img_new)
              cv2.waitKey(1650)
              print("Image Saved")
              print("Program End")
              cv2.destroyAllWindows()
      
              break
          elif cv2.waitKey(1) & 0xFF == ord('q'):
              print("Turning off camera.")
              video_capture.release()
              print("Camera off.")
              print("Program ended.")
              cv2.destroyAllWindows()
              break
      
          # Display the resulting frame
          cv2.imshow('Video', frame)
      
      # When everything is done, release the capture
      video_capture.release()
      cv2.destroyAllWindows()
      

      输出

      另外,你可以查看我的 GitHub code

      【讨论】:

      • 这不能回答问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-08-18
      • 1970-01-01
      • 1970-01-01
      • 2013-06-03
      • 1970-01-01
      • 2013-02-09
      相关资源
      最近更新 更多