IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> 关于OpenCV的坑 -> 正文阅读

[人工智能]关于OpenCV的坑

pip install opencv-python

1. 无法修改摄像头参数

原因1:摄像头不支持此参数
比如:摄像头的帧率最高是30,但是你的电脑CPU带不动它,所以它在你电脑上的帧率只能达到22。

原因2:opencv的问题
我查到一个说法是opencv的权限比驱动低,所以无法修改,可以通过卸载摄像头驱动来修复,这个方法没有测试,看着就不靠谱。

因此就是opencv的问题了。
下面这个代码是广泛流传的打开摄像头代码,

import numpy as np
import cv2
cap = cv2.VideoCapture(0) # 打开摄像头
while(True):
	ret, frame = cap.read() # 读取图片
	cv2.imshow('frame',frame)
	# 退出
	if cv2.waitKey(1) & 0xFF == ord('q'):
		break
cap.release()
cv2.destroyAllWindows()

代码是不存在问题,但是打开摄像头之后无法修改修改相机的参数,比如分辨率、帧率、亮度。

cap = cv2.VideoCapture(camera_number + cv2.CAP_DSHOW)

camera_number就是摄像头在你电脑上的设备号,0,1,2,…
CAP_DSHOW是opencv初始化的一个参数,我找到一个参数列表,适用参数应该与相机的驱动有关系,而我使用的笔记本的摄像头(USB相机),因此使用CAP_DSHOW就行了。

CAP_ANY          = 0             # Auto detect
CAP_VFW          = 200           # Video For Windows (obsolete, removed)
CAP_V4L          = 200           # V4L/V4L2 capturing support
CAP_V4L2         = CAP_V4L       # Same as CAP_V4L
CAP_FIREWIRE     = 300           # IEEE 1394 drivers
CAP_FIREWARE     = CAP_FIREWIRE  # Same value as CAP_FIREWIRE
CAP_IEEE1394     = CAP_FIREWIRE  # Same value as CAP_FIREWIRE
CAP_DC1394       = CAP_FIREWIRE  # Same value as CAP_FIREWIRE
CAP_CMU1394      = CAP_FIREWIRE  # Same value as CAP_FIREWIRE
CAP_QT           = 500           # QuickTime (obsolete, removed)
CAP_UNICAP       = 600           # Unicap drivers (obsolete, removed)
CAP_DSHOW        = 700           # DirectShow (via videoInput)
CAP_PVAPI        = 800           # PvAPI, Prosilica GigE SDK
CAP_OPENNI       = 900           # OpenNI (for Kinect)
CAP_OPENNI_ASUS  = 910           # OpenNI (for Asus Xtion)
CAP_ANDROID      = 1000          # Android - not used
CAP_XIAPI        = 1100          # XIMEA Camera API
CAP_AVFOUNDATION = 1200          # AVFoundation framework for iOS (OS X Lion will have the same API)
CAP_GIGANETIX    = 1300          # Smartek Giganetix GigEVisionSDK
CAP_MSMF         = 1400          # Microsoft Media Foundation (via videoInput)
CAP_WINRT        = 1410          # Microsoft Windows Runtime using Media Foundation
CAP_INTELPERC    = 1500          # RealSense (former Intel Perceptual Computing SDK)
CAP_REALSENSE    = 1500          # Synonym for CAP_INTELPERC
CAP_OPENNI2      = 1600          # OpenNI2 (for Kinect)
CAP_OPENNI2_ASUS = 1610          # OpenNI2 (for Asus Xtion and Occipital Structure sensors)
CAP_GPHOTO2      = 1700          # gPhoto2 connection
CAP_GSTREAMER    = 1800          # GStreamer
CAP_FFMPEG       = 1900          # Open and record video file or stream using the FFMPEG library
CAP_IMAGES       = 2000          # OpenCV Image Sequence (e.g. img_%02d.jpg)
CAP_ARAVIS       = 2100          # Aravis SDK
CAP_OPENCV_MJPEG = 2200          # Built-in OpenCV MotionJPEG codec
CAP_INTEL_MFX    = 2300          # Intel MediaSDK
CAP_XINE         = 2400          # XINE engine (Linux)

这是我写的一个完整Demo

import cv2
import os

# Width, Height
Camera_PROP_640x480 = (640, 480)
Camera_PROP_800x600 = (800, 600)
Camera_PROP_960_640 = (960, 640)
Camera_PROP_1024x540 = (1024, 540)
Camera_PROP_1024x600 = (1024, 600)
Camera_PROP_1024x768 = (1024, 768)
Camera_PROP_1080x960 = (1080, 960)
Camera_PROP_1152x864 = (1152, 864)
Camera_PROP_1280x600 = (1280, 600)
Camera_PROP_1280x720 = (1280, 720)
Camera_PROP_1280x768 = (1280, 768)
Camera_PROP_1280x800 = (1280, 800)
Camera_PROP_1280x960 = (1280, 960)
Camera_PROP_1280x1024 = (1280, 1024)
Camera_PROP_1360x768 = (1360, 768)
Camera_PROP_1366x768 = (1366, 768)
Camera_PROP_1400x1050 = (1400, 1050)
Camera_PROP_1440x900 = (1440, 900)
Camera_PROP_1600x900 = (1600, 900)
Camera_PROP_1680x1050 = (1680, 1050)
Camera_PROP_1920x1080 = (1920, 1080)
Camera_PROP_2048x1080 = (2048, 1080)
Camera_PROP_4096x2160 = (4096, 2160)
Camera_PROP_Max = (300000, 300000)

# 解决显示图片过大导致图片跑到显示器外边
def imshow(winname, mat):
    ratio = mat.shape[0] // 600
    if ratio <= 1:
        ratio = 1.5
    cv2.namedWindow(winname, cv2.WINDOW_NORMAL)
    cv2.resizeWindow(winname, int(mat.shape[1] / ratio), int(mat.shape[0] / ratio))
    cv2.imshow(winname, mat)

if __name__ == '__main__':
    print("=============================================")
    print("=  热键(请在摄像头的窗口使用)                   =")
    print("=  w: 拍摄图片                                =")
    print("=  q: 退出                                   =")
    print("=============================================")
    # 新建文件夹 test
    class_name = 'test'
    if not os.path.exists(class_name):
        os.mkdir(class_name)
    index = 1 
    
	# 打开相机
    cap = cv2.VideoCapture(0 + cv2.CAP_DSHOW)
    # fps = cap.get(cv2.CAP_PROP_FPS)
	
	# 设置相机亮度
    cap.set(cv2.CAP_PROP_BRIGHTNESS, 150)
    print(cap.get(cv2.CAP_PROP_BRIGHTNESS))
	
	# 设置相机增益
    cap.set(cv2.CAP_PROP_GAIN, 1)
    print(cap.get(cv2.CAP_PROP_GAIN))
    
    # 设置相机分辨率
    width, height = Camera_PROP_1280x720
    cap.set(cv2.CAP_PROP_FRAME_WIDTH, width)
    cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
    width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
    height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
    
    # 初始化opencv显示窗口‘capture’
    cv2.namedWindow('capture', cv2.WINDOW_NORMAL)
    cv2.resizeWindow('capture', width // 2, height // 2)
	
	# 设置相机帧率
    cap.set(cv2.CAP_PROP_FPS, 30)
    print(cap.get(cv2.CAP_PROP_FPS))
	
	# 新建一个'test.avi'文件
    fps = 8
    fourcc = cv2.VideoWriter_fourcc(*'XVID')
    out = cv2.VideoWriter('test.avi', fourcc, fps, (width, height))
	
	# 将相机录制到'test.avi'文件中
    while (int(cv2.getWindowProperty('capture', 0)) != -1):
        ret, frame = cap.read() # 获取当前帧
        if not ret:
            continue
        frame = cv2.flip(frame, 1, dst=None) # 镜像
        out.write(frame) # 写入帧
        imshow("capture", frame) # 显示

		# 判断相机退出
        input = cv2.waitKey(1) & 0xFF
        if input == ord('w'):
            cv2.imwrite("%s/%d.png" % (class_name, index), frame)
            print("%s: %d 张图片" % (class_name, index))
            index += 1
        elif input == ord('q'):
            break
	# 释放内存
    out.release()
    cap.release()
    cv2.destroyAllWindows()

2. 中文无法识别

OpenCV的中文乱码问题暂时还无法解决,可以把系统编码修改为UTF8格式来解决这个问题,但是这个方法的代价可能太高了,因此只能使用一些“曲线救国”的办法。

2.1 窗口中文标题无法识别

方法一:改用C++的OpenCV
方法二:改用Python2版本,字符串变为 u’中文’
还是不建议使用中文标题

2.1 中文路径无法识别

import cv2
file_name = '测试/测试.bmp'
img = cv2.imread(file_name)
cv2.imshow('测试',img)
cv2.waitKey()

报错:

cv2.error: OpenCV(4.1.1) C:\projects\opencv-python\opencv\modules\highgui\src\window.cpp:352: error: (-215:Assertion failed) size.width>0 && size.height>0 in function 'cv::imshow'

方法一:
用np.fromfile读取,OpenCV再从内存中读取图片

import cv2
import numpy as np
file_name = '测试/测试.bmp'
img = cv2.imdecode(np.fromfile(file_name, dtype=np.uint8), -1)
cv2.imshow('test',img)
cv2.waitKey()
# 中文路径保存
cv2.imencode('.bmp', img)[1].tofile('测试/测试2.bmp')

方法二:
使用其他库读取图片,然后转成numpy格式再转成OpenCV格式,注意OpenCV是BGR

import cv2
import numpy as np
from PIL import Image
Image.MAX_IMAGE_PIXELS = 1000000000  # 图片最大内存
file_name = '测试/测试.bmp'
img_plt = Image.open(file_name)
# pillow转cv
img_cv = cv2.cvtColor(np.asarray(img_plt), cv2.COLOR_RGB2BGR)
# cv转pillow
img_plt = Image.fromarray(cv2.cvtColor(img_cv, cv2.COLOR_BGR2RGB))
cv2.imshow('test', img_cv)
cv2.waitKey()

方法三:
这个方法跟上一个方法类似,但是我觉得比较有意思,是使用urllib通过url来获取图片,接着转成numpy格式再转为OpenCV格式

import cv2
import numpy as np
from urllib.request import urlopen,pathname2url
file_name = '测试/测试.bmp'
file_url = 'file:' + pathname2url(file_name)
img_url = urlopen(file_url)
img_np = np.asarray(bytearray(img_url.read()), dtype="uint8")
img_cv = cv2.imdecode(img_np, cv2.IMREAD_COLOR)
cv2.imshow('test', img_cv)
cv2.waitKey()

3. 图片转BGR

opencv貌似除了cv2.imread(file_name, 0)外,没有自动匹配位深度转灰度,因此在将图片转灰度需要考虑位深度,否则会报错

def convert_BGR(image):
    """
    转BGR
    :param image:原图像
    """
    if len(image.shape) == 2:
        image = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR)
    elif len(image.shape) == 3:
        if image.shape[2] == 3:
            return image
        elif image.shape[2] == 4:
            image = cv2.cvtColor(image, cv2.COLOR_BGRA2BGR)
        else:
            assert 'image channel too many'
    else:
        assert 'image channel too many'
    return image

4. resize问题

获取图片尺寸用img.shape(),会得到(高,宽,通道数),单通道图片是(高,宽)
但是得到的resize图片的顺序是(宽,高)

img = cv2.resize(img, (width,height))

如果修改图片尺寸,用OpenCV的imshow显示正常,但是传到其他控件考虑会产生裂图(图片显示不正常)
这是因为OpenCV的显示使用了优化,而其他控件打开图片是遵守width,height满足4的倍数
比如PyQt的Qlabel控件显示图片需要将OpenCV的图片转换成QImage,不仅仅是传图片,还要对图片的尺寸进行调整,代码如下:

showImage = QtGui.QImage(show.data, show.shape[1], show.shape[0], show.shape[1] * show.shape[2], QtGui.QImage.Format_RGB888)
  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2021-08-04 11:12:44  更:2021-08-04 11:14:58 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/17 22:45:05-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码