Python:如何使用 OpenCV 在单击时从网络摄像头捕获图像

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34588464/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 15:13:52  来源:igfitidea点击:

Python: how to capture image from webcam on click using OpenCV

pythonpython-2.7opencv

提问by

I want to capture and save a number of images from my webcam using OpenCV. This is my code currently:

我想使用 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)

The problem with this is that I do not know when the images are being taken, so a lot of them end up blurry. My question is: Is there a way to have the image taken on the click of a keyboard key?

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

Also is there a better way to take multiple images, instead of range?

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

回答by danidee

i'm not too experienced with open cv but if you want the code in the for loop to be called when a key is pressed, you can use a while loop and an raw_input and a condition to prevent the loop from executing forever

我对 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)

回答by derricw

Here is a simple program that displays the camera feed in a cv2.namedWindowand will take a snapshot when you hit SPACE. It will also quit if you hit ESC.

这是一个简单的程序,它在 a 中显示相机源,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()

I think this should answer your question for the most part. If there is any line of it that you don't understand let me know and I'll add comments.

我认为这应该在很大程度上回答你的问题。如果您有任何不明白的地方,请告诉我,我会添加评论。

If you need to grab multiple images per press of the SPACEkey, you will need an inner loop or perhaps just make a function that grabs a certain number of images.

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

Note that the key events are from the cv2.namedWindowso it has to have focus.

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

回答by Henrik

Breaking down your code example

分解您的代码示例

import cv2

imports openCV for usage

导入 openCV 以供使用

camera = cv2.VideoCapture(0)

creates an object called camera, of type openCV video capture, using the first camrea in the list of cameras connected to the computer.

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

for i in range(10):

tells the program to loop the following indented code 10 times

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

    return_value, image = camera.read()

read values from the camera object, using it's read method. it resonds with 2 values save the 2 data values into two temporary variables called "return_value" and "image"

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

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

use the openCV method imwrite (that writes an image to a disk) and write an image using the data in the temporary data variable

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

fewer indents means that the loop has now ended...

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

del(camera)

deletes the camrea object, we no longer needs it.

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

you can what you request in many ways, one could be to replace the for loop with a while loop, (running forever, instead of 10 times), and then wait for a keypress (like answerred by danideewhile I was typing)

您可以通过多种方式满足您的要求,其中一种可能是用 while 循环替换 for 循环(永远运行,而不是 10 次),然后等待按键(例如在我打字时由danidee 回答

or create a much more evil service that hides in the background and captures an image everytime someone presses the keyboard..

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

回答by Humayun Ahmad Rajib

Here is a simple programe to capture a image from using laptop default camera.I hope that this will be very easy method for all.

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

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 

You can see my github code here

你可以在这里看到我的github代码

回答by Antu

This is a simple program to capture an image from using a default camera. Also, It can Detect a human face.

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

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()

output

输出

enter image description here

在此处输入图片说明

Also, You can check out my GitHub code

另外,您可以查看我的 GitHub代码