task2:opencv的python接口图像储存、色彩空间、
task2:图像储存、色彩空间、图像的算数运算。
笔记:
使用managers.WindowManager抽象窗口和键盘:
main.py:
import cv2
from manager import WindowManager, CaptureManagerclass Cameo(object):def init (self):self._windowManager = WindowManager('Cameo', self.onKeypress)self._captureManager = CaptureManager(cv2.VideoCapture(0), self._windowManager, True)def run(self):self._windowManager.createWindow()while self._windowManager.isWindowCreated:self._captureManager.enterFrame()frame = self._captureManager.frame
# TODO: Filter the frame (Chapter 3).self._captureManager.exitFrame()self._windowManager.processEvents()def onKeypress (self,keycode):if keycode == 32: # spaceself._captureManager.writelmage('me1.jpg')elif keycode == 9: # tabif not self._captureManager.isWritingVideo:self._captureManager.startwritingvideo('output.avi')else:self._captureManager.stopWritingVideo()elif keycode == 27: # escapeself._windowManager.destroyWindow()if __name__ == '__main__':Cameo().run()
manager.py:
import cv2
class CaptureManager(object):def init (self, capture, previewWindowManager = None,shouldMirrorPreview = False):self.previewWindowManager = previewWindowManagerself.shouldMirrorPreview = shouldMirrorPreviewself._capture = captureself._channel = 0self. enteredFrame = Falseself._frame = Noneself._imageFilename = Noneself._videoFilename = Noneself._videoEncoding = Noneself._videoWriter = Noneself._startTime = Noneself._framesElapsed = int(0)self._fpsEstimate = None@propertydef channel(self):return self._channel@channel.setterdef channel(self, value):if self._channel != value:self._channel = valueself._frame = None@propertydef frame(self):if self._enteredFrame and self._frame is None:self._frame = self._capture.retrieve()return self._frame@propertydef isWritinglmage (self):return self._imageFilename is not None@propertydef isWritingVideo(self):return self._videoFilename is not Noneclass WindowManager(object):def init (self, windowName,keypressCallback = None):self.keypressCallback = keypressCallbackself._windowName = windowNameself._isWindowCreated = False@propertydef isWindowCreated(self):return self._isWindowCreateddef createWindow (self):cv2.namedWindow(self._windowName)self._isWindowCreated = Truedef show(self, frame):cv2.imshow(self._windowName, frame)def destroyWindow (self):cv2.destroyWindow(self._windowName)self._isWindowCreated = Falsedef processEvents (self):keycode = cv2.waitKey(1)if self.keypressCallback is not None and keycode != -1:
# Discard any non-ASCII info encoded by GTK.self.keypressCallback(keycode)
ps:这个代码运行以后显示:
File “C:\Users\14172\PycharmProjects\pythonProject3\main.py”, line
25, in run
self._windowManager.createWindow() AttributeError: ‘Cameo’ object has no attribute ‘_windowManager’
还没找出问题。
HSV和RGB
OpenCV中有数百种关于在不同色彩空间之间转换的方法。当前,在计算机视觉中有三 种常用的色彩空间:灰度、BGR以及HSV (Hue, Saturation, Value)o
□灰度色彩空间是通过去除彩色信息来将其转换成灰阶,灰度色彩空间对中间处理特 别有效,比如人脸检测。
□ BGR,即蓝-绿-红色彩空间,每一个像素点都由一个三元数组来表示,分别代表 蓝、绿、红三种颜色。网页开发者可能熟悉另一个与之相似的颜色空间:RGB,它 们只是在颜色的顺序上不同。
□ HSV, H ( Hue)是色调,S ( Saturation)是饱和度,V (Value)表示黑暗的程度(或 光谱另一端的明亮程度)。
BGR图像中像素B,G和R的取值与落在物体上的光相关,因此这些值也彼此相关,无法准确描述像素。相反,HSV空间中,三者相对独立,可以准确描述像素的亮度,饱和度和色度。
RGB色彩空间是一种被广泛接受的色彩空间,但是它过于抽象,我们不能直接通过其值感知具体的色彩,HSV色彩空间我们可以更加方便地通过色调 饱和度 亮度来感知颜色。
H色调 S饱和度 V亮度 色调0为红色,300为品红色
亮度为0时图像是纯黑色
img[0,0,0]=255将该像素点第0个通道(即B通道)设置为255,即该点指定为蓝色。
绿色的色调为60 蓝色为120
示例:
blue = np.zeros([1,1,3],dtype=np.uint8)
blue[0,0,0] = 255
bluet0 = cv2.cvtColor(blue,cv2.COLOR_BGR2HSV)
print(blue)
print(bluet0)
结果:
HSV模式中各种颜色的范围:
蓝色-[110,100,100]到[130,255,255]之间
绿色-值在[50,100,100]和,[70,255,255]之间
红色-[0,100,100], [10,255,255]之间
通过掩码的按位与运算,锁定颜色区域:
img = cv2.imread("me1.jpg")
img2 = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
minred =np.array( [0,50,50])
maxred = np.array([30,255,255])
#确定红色区域
mask = cv2.inRange(img2,minred,maxred)
#按位与运算 提取蓝色区域
img3 = cv2.bitwise_and(img,img,mask=mask)
cv2.imshow("img",img3)
结果:=
傅里叶变换
在OpenCV中,对图像和视频的大多数处理都或多或少会涉及傅里叶变换的概念。
也就是说,人们所看到的波形都是由其他波形叠加得到的。这个概念对操作图像非常 有帮助,因为这样我们可以区分图像里哪些区域的信号(比如图像像素)变化特别强,哪些区域的信号变化不那么强,从而可以任意地标记噪声区域、感兴趣区域、前景和背景等。 原始图像由许多频率组成,人们能够分离这些频率来理解图像和提取感兴趣的数据。
傅里叶变换的概念是许多常见的图像处理操作的基础,比如边缘检测或线段和形状 检测。
下面先介绍两个概念:高通滤波器和低通滤波器,上面提到的那些操作都是以这两个 概念和傅里叶变换为基础。
3.2.1高通滤波器
高通滤波器(HPF)是检测图像的某个区域,然后根据像素与周围像素的亮度差值来提 升(boost)该像素的亮度的滤波器。
边缘检测
OpenCV提供了许多边缘检测滤波函数,包括Laplacian、Sobel()以及Scharr()这些滤波函数都会将非边缘区域转为黑色,将边缘区域转为白色或其他饱和的颜色。但是, 这些函数都很容易将噪声错误地识别为边缘。缓解这个问题的方法是在找到边缘之前对图 像进行模糊处理。OpenCV也提供了许多模糊滤波函数,包括blur()(简单的算术平均)、 medianBlur()以及GaussianBlur()。边缘检测滤波函数和模糊滤波函数的参数有很多,但总会有一个ksize参数,它是一个奇数,表示滤波核的宽和高(以像素为单位)。
这里使用medianBlur()作为模糊函数,它对去除数字化的视频噪声•非常有效,特别是去除彩色图像的噪声;使用Laplacian()作为边缘检测函数,它会产生明显的边缘线条,灰度图像更是如此。在使用medianBlur()函数之后,将要使用L aplacian ()函数之前,需要将 图像从BGR色彩空间转为灰度色彩空间。
在得到Laplacian()函数的结果之后,需要将其转换成黑色边缘和白色背景的图像。然 后将其归一化(使它的像素值在0到1之间),并乘以源图像以便能将边缘变黑。
代码测试
flags = [i for i in dir(cv) if i.startswith('COLOR_')]print(flags)
输出:
C:\Users\14172\PycharmProjects\pythonProject3\venv\Scripts\python.exe C:/Users/14172/PycharmProjects/pythonProject3/main.py
[‘COLOR_BAYER_BG2BGR’, ‘COLOR_BAYER_BG2BGRA’, ‘COLOR_BAYER_BG2BGR_EA’, ‘COLOR_BAYER_BG2BGR_VNG’, ‘COLOR_BAYER_BG2GRAY’, ‘COLOR_BAYER_BG2RGB’, ‘COLOR_BAYER_BG2RGBA’, ‘COLOR_BAYER_BG2RGB_EA’, ‘COLOR_BAYER_BG2RGB_VNG’, ‘COLOR_BAYER_GB2BGR’, ‘COLOR_BAYER_GB2BGRA’, ‘COLOR_BAYER_GB2BGR_EA’, ‘COLOR_BAYER_GB2BGR_VNG’, ‘COLOR_BAYER_GB2GRAY’, ‘COLOR_BAYER_GB2RGB’, ‘COLOR_BAYER_GB2RGBA’, ‘COLOR_BAYER_GB2RGB_EA’, ‘COLOR_BAYER_GB2RGB_VNG’, ‘COLOR_BAYER_GR2BGR’, ‘COLOR_BAYER_GR2BGRA’, ‘COLOR_BAYER_GR2BGR_EA’, ‘COLOR_BAYER_GR2BGR_VNG’, ‘COLOR_BAYER_GR2GRAY’, ‘COLOR_BAYER_GR2RGB’, ‘COLOR_BAYER_GR2RGBA’, ‘COLOR_BAYER_GR2RGB_EA’, ‘COLOR_BAYER_GR2RGB_VNG’, ‘COLOR_BAYER_RG2BGR’, ‘COLOR_BAYER_RG2BGRA’, ‘COLOR_BAYER_RG2BGR_EA’, ‘COLOR_BAYER_RG2BGR_VNG’, ‘COLOR_BAYER_RG2GRAY’, ‘COLOR_BAYER_RG2RGB’, ‘COLOR_BAYER_RG2RGBA’, ‘COLOR_BAYER_RG2RGB_EA’, ‘COLOR_BAYER_RG2RGB_VNG’, ‘COLOR_BGR2BGR555’, ‘COLOR_BGR2BGR565’, ‘COLOR_BGR2BGRA’, ‘COLOR_BGR2GRAY’, ‘COLOR_BGR2HLS’, ‘COLOR_BGR2HLS_FULL’, ‘COLOR_BGR2HSV’, ‘COLOR_BGR2HSV_FULL’, ‘COLOR_BGR2LAB’, ‘COLOR_BGR2LUV’, ‘COLOR_BGR2Lab’, ‘COLOR_BGR2Luv’, ‘COLOR_BGR2RGB’, ‘COLOR_BGR2RGBA’, ‘COLOR_BGR2XYZ’, ‘COLOR_BGR2YCR_CB’, ‘COLOR_BGR2YCrCb’, ‘COLOR_BGR2YUV’, ‘COLOR_BGR2YUV_I420’, ‘COLOR_BGR2YUV_IYUV’, ‘COLOR_BGR2YUV_YV12’, ‘COLOR_BGR5552BGR’, ‘COLOR_BGR5552BGRA’, ‘COLOR_BGR5552GRAY’, ‘COLOR_BGR5552RGB’, ‘COLOR_BGR5552RGBA’, ‘COLOR_BGR5652BGR’, ‘COLOR_BGR5652BGRA’, ‘COLOR_BGR5652GRAY’, ‘COLOR_BGR5652RGB’, ‘COLOR_BGR5652RGBA’, ‘COLOR_BGRA2BGR’, ‘COLOR_BGRA2BGR555’, ‘COLOR_BGRA2BGR565’, ‘COLOR_BGRA2GRAY’, ‘COLOR_BGRA2RGB’, ‘COLOR_BGRA2RGBA’, ‘COLOR_BGRA2YUV_I420’, ‘COLOR_BGRA2YUV_IYUV’, ‘COLOR_BGRA2YUV_YV12’, ‘COLOR_BayerBG2BGR’, ‘COLOR_BayerBG2BGRA’, ‘COLOR_BayerBG2BGR_EA’, ‘COLOR_BayerBG2BGR_VNG’, ‘COLOR_BayerBG2GRAY’, ‘COLOR_BayerBG2RGB’, ‘COLOR_BayerBG2RGBA’, ‘COLOR_BayerBG2RGB_EA’, ‘COLOR_BayerBG2RGB_VNG’, ‘COLOR_BayerGB2BGR’, ‘COLOR_BayerGB2BGRA’, ‘COLOR_BayerGB2BGR_EA’, ‘COLOR_BayerGB2BGR_VNG’, ‘COLOR_BayerGB2GRAY’, ‘COLOR_BayerGB2RGB’, ‘COLOR_BayerGB2RGBA’, ‘COLOR_BayerGB2RGB_EA’, ‘COLOR_BayerGB2RGB_VNG’, ‘COLOR_BayerGR2BGR’, ‘COLOR_BayerGR2BGRA’, ‘COLOR_BayerGR2BGR_EA’, ‘COLOR_BayerGR2BGR_VNG’, ‘COLOR_BayerGR2GRAY’, ‘COLOR_BayerGR2RGB’, ‘COLOR_BayerGR2RGBA’, ‘COLOR_BayerGR2RGB_EA’, ‘COLOR_BayerGR2RGB_VNG’, ‘COLOR_BayerRG2BGR’, ‘COLOR_BayerRG2BGRA’, ‘COLOR_BayerRG2BGR_EA’, ‘COLOR_BayerRG2BGR_VNG’, ‘COLOR_BayerRG2GRAY’, ‘COLOR_BayerRG2RGB’, ‘COLOR_BayerRG2RGBA’, ‘COLOR_BayerRG2RGB_EA’, ‘COLOR_BayerRG2RGB_VNG’, ‘COLOR_COLORCVT_MAX’, ‘COLOR_GRAY2BGR’, ‘COLOR_GRAY2BGR555’, ‘COLOR_GRAY2BGR565’, ‘COLOR_GRAY2BGRA’, ‘COLOR_GRAY2RGB’, ‘COLOR_GRAY2RGBA’, ‘COLOR_HLS2BGR’, ‘COLOR_HLS2BGR_FULL’, ‘COLOR_HLS2RGB’, ‘COLOR_HLS2RGB_FULL’, ‘COLOR_HSV2BGR’, ‘COLOR_HSV2BGR_FULL’, ‘COLOR_HSV2RGB’, ‘COLOR_HSV2RGB_FULL’, ‘COLOR_LAB2BGR’, ‘COLOR_LAB2LBGR’, ‘COLOR_LAB2LRGB’, ‘COLOR_LAB2RGB’, ‘COLOR_LBGR2LAB’, ‘COLOR_LBGR2LUV’, ‘COLOR_LBGR2Lab’, ‘COLOR_LBGR2Luv’, ‘COLOR_LRGB2LAB’, ‘COLOR_LRGB2LUV’, ‘COLOR_LRGB2Lab’, ‘COLOR_LRGB2Luv’, ‘COLOR_LUV2BGR’, ‘COLOR_LUV2LBGR’, ‘COLOR_LUV2LRGB’, ‘COLOR_LUV2RGB’, ‘COLOR_Lab2BGR’, ‘COLOR_Lab2LBGR’, ‘COLOR_Lab2LRGB’, ‘COLOR_Lab2RGB’, ‘COLOR_Luv2BGR’, ‘COLOR_Luv2LBGR’, ‘COLOR_Luv2LRGB’, ‘COLOR_Luv2RGB’, ‘COLOR_M_RGBA2RGBA’, ‘COLOR_RGB2BGR’, ‘COLOR_RGB2BGR555’, ‘COLOR_RGB2BGR565’, ‘COLOR_RGB2BGRA’, ‘COLOR_RGB2GRAY’, ‘COLOR_RGB2HLS’, ‘COLOR_RGB2HLS_FULL’, ‘COLOR_RGB2HSV’, ‘COLOR_RGB2HSV_FULL’, ‘COLOR_RGB2LAB’, ‘COLOR_RGB2LUV’, ‘COLOR_RGB2Lab’, ‘COLOR_RGB2Luv’, ‘COLOR_RGB2RGBA’, ‘COLOR_RGB2XYZ’, ‘COLOR_RGB2YCR_CB’, ‘COLOR_RGB2YCrCb’, ‘COLOR_RGB2YUV’, ‘COLOR_RGB2YUV_I420’, ‘COLOR_RGB2YUV_IYUV’, ‘COLOR_RGB2YUV_YV12’, ‘COLOR_RGBA2BGR’, ‘COLOR_RGBA2BGR555’, ‘COLOR_RGBA2BGR565’, ‘COLOR_RGBA2BGRA’, ‘COLOR_RGBA2GRAY’, ‘COLOR_RGBA2M_RGBA’, ‘COLOR_RGBA2RGB’, ‘COLOR_RGBA2YUV_I420’, ‘COLOR_RGBA2YUV_IYUV’, ‘COLOR_RGBA2YUV_YV12’, ‘COLOR_RGBA2mRGBA’, ‘COLOR_XYZ2BGR’, ‘COLOR_XYZ2RGB’, ‘COLOR_YCR_CB2BGR’, ‘COLOR_YCR_CB2RGB’, ‘COLOR_YCrCb2BGR’, ‘COLOR_YCrCb2RGB’, ‘COLOR_YUV2BGR’, ‘COLOR_YUV2BGRA_I420’, ‘COLOR_YUV2BGRA_IYUV’, ‘COLOR_YUV2BGRA_NV12’, ‘COLOR_YUV2BGRA_NV21’, ‘COLOR_YUV2BGRA_UYNV’, ‘COLOR_YUV2BGRA_UYVY’, ‘COLOR_YUV2BGRA_Y422’, ‘COLOR_YUV2BGRA_YUNV’, ‘COLOR_YUV2BGRA_YUY2’, ‘COLOR_YUV2BGRA_YUYV’, ‘COLOR_YUV2BGRA_YV12’, ‘COLOR_YUV2BGRA_YVYU’, ‘COLOR_YUV2BGR_I420’, ‘COLOR_YUV2BGR_IYUV’, ‘COLOR_YUV2BGR_NV12’, ‘COLOR_YUV2BGR_NV21’, ‘COLOR_YUV2BGR_UYNV’, ‘COLOR_YUV2BGR_UYVY’, ‘COLOR_YUV2BGR_Y422’, ‘COLOR_YUV2BGR_YUNV’, ‘COLOR_YUV2BGR_YUY2’, ‘COLOR_YUV2BGR_YUYV’, ‘COLOR_YUV2BGR_YV12’, ‘COLOR_YUV2BGR_YVYU’, ‘COLOR_YUV2GRAY_420’, ‘COLOR_YUV2GRAY_I420’, ‘COLOR_YUV2GRAY_IYUV’, ‘COLOR_YUV2GRAY_NV12’, ‘COLOR_YUV2GRAY_NV21’, ‘COLOR_YUV2GRAY_UYNV’, ‘COLOR_YUV2GRAY_UYVY’, ‘COLOR_YUV2GRAY_Y422’, ‘COLOR_YUV2GRAY_YUNV’, ‘COLOR_YUV2GRAY_YUY2’, ‘COLOR_YUV2GRAY_YUYV’, ‘COLOR_YUV2GRAY_YV12’, ‘COLOR_YUV2GRAY_YVYU’, ‘COLOR_YUV2RGB’, ‘COLOR_YUV2RGBA_I420’, ‘COLOR_YUV2RGBA_IYUV’, ‘COLOR_YUV2RGBA_NV12’, ‘COLOR_YUV2RGBA_NV21’, ‘COLOR_YUV2RGBA_UYNV’, ‘COLOR_YUV2RGBA_UYVY’, ‘COLOR_YUV2RGBA_Y422’, ‘COLOR_YUV2RGBA_YUNV’, ‘COLOR_YUV2RGBA_YUY2’, ‘COLOR_YUV2RGBA_YUYV’, ‘COLOR_YUV2RGBA_YV12’, ‘COLOR_YUV2RGBA_YVYU’, ‘COLOR_YUV2RGB_I420’, ‘COLOR_YUV2RGB_IYUV’, ‘COLOR_YUV2RGB_NV12’, ‘COLOR_YUV2RGB_NV21’, ‘COLOR_YUV2RGB_UYNV’, ‘COLOR_YUV2RGB_UYVY’, ‘COLOR_YUV2RGB_Y422’, ‘COLOR_YUV2RGB_YUNV’, ‘COLOR_YUV2RGB_YUY2’, ‘COLOR_YUV2RGB_YUYV’, ‘COLOR_YUV2RGB_YV12’, ‘COLOR_YUV2RGB_YVYU’, ‘COLOR_YUV420P2BGR’, ‘COLOR_YUV420P2BGRA’, ‘COLOR_YUV420P2GRAY’, ‘COLOR_YUV420P2RGB’, ‘COLOR_YUV420P2RGBA’, ‘COLOR_YUV420SP2BGR’, ‘COLOR_YUV420SP2BGRA’, ‘COLOR_YUV420SP2GRAY’, ‘COLOR_YUV420SP2RGB’, ‘COLOR_YUV420SP2RGBA’, ‘COLOR_YUV420p2BGR’, ‘COLOR_YUV420p2BGRA’, ‘COLOR_YUV420p2GRAY’, ‘COLOR_YUV420p2RGB’, ‘COLOR_YUV420p2RGBA’, ‘COLOR_YUV420sp2BGR’, ‘COLOR_YUV420sp2BGRA’, ‘COLOR_YUV420sp2GRAY’, ‘COLOR_YUV420sp2RGB’, ‘COLOR_YUV420sp2RGBA’, ‘COLOR_mRGBA2RGBA’]
Process finished with exit code 0
在蓝色物体附件画圈:
import cv2 as cv
import numpy as np
if __name__ == '__main__':cap = cv.VideoCapture(0)while (1):# Take each frame_, frame = cap.read()# Convert BGR to HSVhsv = cv.cvtColor(frame, cv.COLOR_BGR2HSV)# define range of blue color in HSVlower_blue = np.array([110, 50, 50])upper_blue = np.array([130, 255, 255])# Threshold the HSV image to get only blue colorsmask = cv.inRange(hsv, lower_blue, upper_blue)# Bitwise-AND mask and original imageres = cv.bitwise_and(frame, frame, mask=mask)cv.imshow('frame', frame)cv.imshow('mask', mask)cv.imshow('res', res)k = cv.waitKey(5) & 0xFFif k == 27:breakcv.destroyAllWindows()
效果:
将参数修改
lower_blue = np.array([100, 50, 50])
之后效果:
一份用c++画矩形的代码:
#include "opencv2/opencv.hpp"
using namespace cv;void main()
{Mat src = imread("bird.jpg");Rect rect(230, 5, 280, 290);//左上坐标(x,y)和矩形的长(x)宽(y)cv::rectangle(src, rect, Scalar(255, 0, 0),1, LINE_8,0);//cv::rectangle(src, Point(230, 5), Point(510, 295), Scalar(255, 0, 0), 1, LINE_8, 0);//左上角点的(x,y),右下角点的(x,y)// cv::rectangle(src, rect, Scalar(255, 0, 0),-1, LINE_8,0);//绘制填充矩形imwrite("src.png", src);imshow("src", src);waitKey(0);}
习题
代码调用电脑摄像头,寻找视野中任意颜色(自定)并具有一定大小的物体,并用矩形框处,最后显示在图像上;
知道了怎么用圆形框住,还没有框矩形:
代码:
cap = cv.VideoCapture(0)while True:# 读取每一帧_, frame = cap.read()# 重设图片尺寸以提高计算速度frame = imutils.resize(frame, width=600)# 进行高斯模糊blurred = cv.GaussianBlur(frame, (11, 11), 0)# 转换颜色空间到HSVhsv = cv.cvtColor(blurred, cv.COLOR_BGR2HSV)# 定义蓝色阈值lower_red = np.array([100, 100, 100])upper_red = np.array([130, 255, 255])# 对图片进行二值化处理mask = cv.inRange(hsv, lower_red, upper_red)# 腐蚀操作mask = cv.erode(mask, None, iterations=2)# 膨胀操作,先腐蚀后膨胀以滤除噪声mask = cv.dilate(mask, None, iterations=2)cv.imshow('mask', mask)# 寻找图中轮廓cnts = cv.findContours(mask.copy(), cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)[-2]# 如果存在至少一个轮廓则进行如下操作if len(cnts) > 0:# 找到面积最大的轮廓c = max(cnts, key=cv.contourArea)# 使用最小外接圆圈出面积最大的轮廓((x, y), radius) = cv.minEnclosingCircle(c)# 计算轮廓的矩M = cv.moments(c)# 计算轮廓的重心center = (int(M["m10"] / M["m00"]), int(M["m01"] / M["m00"]))# 只处理尺寸足够大的轮廓if radius > 5:# 画出最小外接圆cv.circle(frame, (int(x), int(y)), int(radius), (0, 255, 255), 2)# 画出重心cv.circle(frame, center, 5, (0, 0, 255), -1)cv.imshow('frame', frame)k = cv.waitKey(5) & 0xFFif k == 27:break
cap.release()
cv.destroyAllWindows()
效果:
框正矩形:
其余句子不变,if后面改成这个:
if len(cnts) > 0:# 找到面积最大的轮廓c = max(cnts, key=cv.contourArea)# 使用最小外接圆圈出面积最大的轮廓x,y,w,h = cv.boundingRect(c)cv.rectangle(frame,(x,y), (x+w,y+h), (0, 255, 255), 2)
cv2.boundingRect(img)这个函数很简单,img是一个二值图,也就是它的参数;返回四个值,分别是x,y,w,h;
x,y是矩阵左上点的坐标,w,h是矩阵的宽和高
换一个颜色试试:
阈值设置要准确,才能正确框住。
还有一个框斜矩形的:
minAreaRect函数返回矩形的中心点坐标,长宽,旋转角度[-90,0),当矩形水平或竖直时均返回-90
以rect作为它的返回值则有:
centar = rect[0] width,height = rect[1] (注意第二个返回值是一个数组)
if __name__ == '__main__':img = cv2.imread("me1.jpg")cv2.rectangle(img, (130, 250), (200,400), (0, 255, 0), 2)cv2.imshow("nn",img)cv2.waitKey()
提取轮廓:
import cv2if __name__ == '__main__':img = cv2.imread("me1.jpg")gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)ret, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)cv2.drawContours(img, contours, -1, (0, 0, 255), 3)cv2.imshow("img", img)cv2.waitKey(0)
效果:
框一定颜色的物块:(中间的绿线还不知道咋出来的。。。
img = cv2.imread('66.png')# 颜色转换函数 转换为hsv cv2.COLOR_BGR2HSVhsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)low_hsv = np.array([11, 43, 46])high_hsv = np.array([100, 255, 255])mask = cv2.inRange(hsv, lowerb=low_hsv, upperb=high_hsv)# 中值滤波降噪median = cv2.medianBlur(mask, 5)# 进行边缘检测np.array([30, 43, 46])# mask是只突出指定颜色的图片cannyPic = cv2.Canny(median, 10, 200)line = 50minLineLength = 10maxLineGap = 150# 检测直线函数,能输出检测到的直线端点lines = cv2.HoughLinesP(cannyPic, 1, np.pi / 180, 120, lines=line, minLineLength=minLineLength,maxLineGap=maxLineGap)lines1 = lines[:, 0, :]# line()划线函数for x1, y1, x2, y2 in lines1:cv2.line(img, (x1, y1), (x2, y2), (0, 255, 0), 2)contours, hierarchy = cv2.findContours(cannyPic, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)for c in contours:rect = cv2.minAreaRect(c)box_ = cv2.boxPoints(rect)h = abs(box_[3, 1] - box_[1, 1])w = abs(box_[3, 0] - box_[1, 0])box = cv2.boxPoints(rect) # 计算最小面积矩形的坐标box = np.int0(box) # 将坐标规范化为整数angle = rect[2]if angle > 20:continue# 绘制矩形cv2.drawContours(img, [box], 0, (255, 0, 0), 3)cv2.namedWindow("img_3", 0)cv2.imshow("img_3", img)cv2.waitKey(0)cv2.destroyAllWindows()
然后发现有的颜色还没有框住。。
一个框住一定物体的代码:
img = cv2.pyrDown(cv2.imread("hammer.png" ,cv2.IMREAD_UNCHANGED))ret, thresh = cv2.threshold(cv2.cvtColor(img.copy(),cv2.COLOR_BGR2GRAY), 127, 255, cv2.THRESH_BINARY)image,contours= cv2.findContours(thresh,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)for c in contours:# find bounding box coordinatesx, y, w, h = cv2.boundingRect(c)cv2.rectangle(img, (x, y), (x+w, y + h), (0, 255, 0), 2)# find minimum arearect = cv2.minAreaRect(c)# calculate coordinates of the minimum area rectanglebox = cv2.boxPoints(rect)# normalize coordinates to integersbox = np.into(box)# draw contourscv2.drawContours(img, [box], 0, (0, 0, 255), 3)# calculate center and radius of minimum enclosing circle(x, y),radius = cv2.minEnclosingCircle(c)# cast to integerscenter = (int(x), int(y))radius = int(radius)# draw the circleimg = cv2.circle(img, center, radius, (0, 255, 0),2)cv2.drawContours(img, contours, -1, (255, 0, 0),1)cv2.imshow("contoursn", img)
原图:
不知道代码是哪里出了bug 还没跑成功:
关键是好多函数还不知道是怎么用的。。。
追踪特定颜色:
import imutilsif __name__ == '__main__':cap = cv.VideoCapture(0)while True:# 读取每一帧_, frame = cap.read()# 重设图片尺寸以提高计算速度frame = imutils.resize(frame, width=600)# 进行高斯模糊blurred = cv.GaussianBlur(frame, (11, 11), 0)# 转换颜色空间到HSVhsv = cv.cvtColor(blurred, cv.COLOR_BGR2HSV)# 定义红色无图的HSV阈值lower_red = np.array([20, 100, 100])upper_red = np.array([220, 255, 255])# 对图片进行二值化处理mask = cv.inRange(hsv, lower_red, upper_red)# 腐蚀操作mask = cv.erode(mask, None, iterations=2)# 膨胀操作,先腐蚀后膨胀以滤除噪声mask = cv.dilate(mask, None, iterations=2)cv.imshow('mask', mask)# 寻找图中轮廓cnts = cv.findContours(mask.copy(), cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)[-2]# 如果存在至少一个轮廓则进行如下操作if len(cnts) > 0:# 找到面积最大的轮廓c = max(cnts, key=cv.contourArea)# 使用最小外接圆圈出面积最大的轮廓((x, y), radius) = cv.minEnclosingCircle(c)# 计算轮廓的矩M = cv.moments(c)# 计算轮廓的重心center = (int(M["m10"] / M["m00"]), int(M["m01"] / M["m00"]))# 只处理尺寸足够大的轮廓if radius > 5:# 画出最小外接圆cv.rectangle(frame, (int(x), int(y)), (int(x), int(y)), (0, 255, 255), 2)# 画出重心cv.imshow('frame', frame)k = cv.waitKey(5) & 0xFFif k == 27:breakcap.release()cv.destroyAllWindows()
不知道为什么只有试蓝色物体的时候才有阴影。。。然后圆形框也没出来。。。。。
追踪:
if __name__ == '__main__':cap = cv2.VideoCapture(0) # 获取摄像头视频while True:ret, frame = cap.read() # 读取每一帧图片hsv_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) # 将每一帧图片转化HSV空间颜色lower = np.array([0, 104, 205])upper = np.array([15, 208, 255])mask = cv2.inRange(hsv_frame, lower, upper)img, conts = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 找出边界cv2.drawContours(frame, conts, -1, (0, 255, 0), 3) # 画出边框dst = cv2.bitwise_and(frame, frame, mask=mask) # 对每一帧进行位与操作,获取追踪图像的颜色# cv2.imshow("mask",mask)# cv2.imshow("dst",dst)cv2.imshow("frame", frame)if cv2.waitKey(1) & 0xff == 27:breakcv2.destroyAllWindows()
动态识别物体:
import cv2
import numpy as npcamera = cv2.VideoCapture(0) # 参数0表示第一个摄像头
# 判断视频是否打开
if (camera.isOpened()):print('Open')
else:print('摄像头未打开')# 测试用,查看视频size
size = (int(camera.get(cv2.CAP_PROP_FRAME_WIDTH)),int(camera.get(cv2.CAP_PROP_FRAME_HEIGHT)))
print('size:' + repr(size))es = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (9, 4))
kernel = np.ones((5, 5), np.uint8)
background = Nonewhile True:# 读取视频流grabbed, frame_lwpCV = camera.read()# 对帧进行预处理,先转灰度图,再进行高斯滤波。# 用高斯滤波进行模糊处理,进行处理的原因:每个输入的视频都会因自然震动、光照变化或者摄像头本身等原因而产生噪声。对噪声进行平滑是为了避免在运动和跟踪时将其检测出来。gray_lwpCV = cv2.cvtColor(frame_lwpCV, cv2.COLOR_BGR2GRAY)gray_lwpCV = cv2.GaussianBlur(gray_lwpCV, (21, 21), 0)# 将第一帧设置为整个输入的背景if background is None:background = gray_lwpCVcontinue# 对于每个从背景之后读取的帧都会计算其与北京之间的差异,并得到一个差分图(different map)。# 还需要应用阈值来得到一幅黑白图像,并通过下面代码来膨胀(dilate)图像,从而对孔(hole)和缺陷(imperfection)进行归一化处理diff = cv2.absdiff(background, gray_lwpCV)diff = cv2.threshold(diff, 148, 255, cv2.THRESH_BINARY)[1] # 二值化阈值处理diff = cv2.dilate(diff, es, iterations=2) # 形态学膨胀# 显示矩形框image, contours, hierarchy = cv2.findContours(diff.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) # 该函数计算一幅图像中目标的轮廓for c in contours:if cv2.contourArea(c) < 1500: # 对于矩形区域,只显示大于给定阈值的轮廓,所以一些微小的变化不会显示。对于光照不变和噪声低的摄像头可不设定轮廓最小尺寸的阈值continue(x, y, w, h) = cv2.boundingRect(c) # 该函数计算矩形的边界框cv2.rectangle(frame_lwpCV, (x, y), (x + w, y + h), (0, 255, 0), 2)cv2.imshow('contours', frame_lwpCV)cv2.imshow('dis', diff)key = cv2.waitKey(1) & 0xFF# 按'q'健退出循环if key == ord('q'):break# When everything done, release the capture
camera.release()
cv2.destroyAllWindows()
感觉可能是opencv4发生了改动,这个代码在我的电脑上一直报错:
还没时间看官方文档,以后再看吧
task2:opencv的python接口图像储存、色彩空间、相关推荐
- OpenCV的Python接口
Python教程系列:http://blog.csdn.net/sunny2038/article/details/9057415 与C++的不同之处:http://developer.51cto.c ...
- 使用OpenCV和Python计算图像的“彩色度”
使用OpenCV和Python计算图像"彩色度" 1. 效果图 2. 炫彩度量方法是什么? 3. 源代码 参考 你是否尝试过计算每个图像的炫彩值,并根据炫彩值对自己的图像数据集进行 ...
- 使用OpenCV和Python从图像中提取形状
Welcome to the first post in this series of blogs on extracting features from images using OpenCV an ...
- OpenCV for Python之图像RIO与泛洪填充
OpenCV for Python之图像RIO与泛洪填充 1 ROI与泛函填充 2 ROI 3 泛洪填充 Opencv4 官方文档 : https://docs.opencv.org/4.2.0/ O ...
- opencv for python的图像梯度算子以及canny边缘检测
opencv for python的图像梯度算子以及canny边缘检测 一.图像梯度算子: 二.Canny边缘检测(一个多级边缘检测算法): 一.图像梯度算子: 1.概念简介(部分引自百度百科): 图 ...
- 使用OpenCV,Python进行图像哈希(差分哈希 dHash)处理
使用OpenCV,Phthon进行图像哈希处理的一个重要应用是去除重复的图像: 当你有多个相册的图片,进行合并时,so boring,有一些图片是重复的,肉眼来看太难删除了. 图像哈希可以帮助你完美的 ...
- 使用opencv和python实现图像的智能处理_机器学习:使用opencv和python进行智能图像处理...
译者序 序 前言 审校者简介 章 品味机器学习 1 1.1 初步了解机器学习 1 1.2 机器学习可以解决的事情 3 1.3 初步了解 Python 4 1.4 初步了解 OpenCV 4 1.5 安 ...
- 使用opencv和python实现图像的智能处理pdf_机器学习:基于OpenCV和Python的智能图像处理...
前言 图像处理又称为数字图像处理,是指对图像进行分析.加工和处理,使其满足视觉方面需求的一种技术,它也是信号处理在图像领域的一种重要应用.随着计算机技术.人工智能和思维科学研究的迅速发展,图像处理向更 ...
- Cmake 坑爹让我在Ubuntu14.04 安装opencv的python接口库搞了一整天
一.前几天在ubuntu14.04系统上通过源码安装了opencv3.1后,在python控制台输入 import cv2 提示找不到cv2库.我赶紧百度找了下原因,网上说执行这个命令就行 sudo ...
最新文章
- CVPR 2020 | 更高质量的点云补全:上海交通大学团队提出点云分形网络
- 在MM32F3273上运行MicroPython,对于性能进行测试
- UVA11054Gergovia的酒交易
- 帮助你驾驭 Kubernetes 的 4 个工具 | Linux 中国
- # 57. 插入区间
- mybatis入门基础(五)----动态SQL
- 台风路径超级计算机,厄尔尼诺又要来了?2号台风或要生成,超级计算机:路径争议大...
- python调用r语言加载包错误_Python中调用R语言包指南.docx
- L1-046 整除光棍 (20 分)—团体程序设计天梯赛
- FFmpeg学习(1)——视频文件格式转换
- HTML5实现在线拍照功能(调取摄像头API)
- 利用python实现杜利特尔分解法
- Pandas学习——分组
- 创建自己的SQL Server Management Studio 17(SSMS)扩展
- LFY-SpringBoot2【SpringBoot2入门】
- 要写码,又要做年终总结PPT?高效神器保住你的发际线
- Android Studio Lint 工具看完这一篇还不够
- Python的wheel文件安装
- asr标注工具_传统ASR全流程【转载】
- (zz)Lambda 表达式(C# 编程指南)
热门文章
- spark-submit
- comsol稀物质传递_什么是质量传递?
- 复合火焰探测传感器_火灾探测器分类
- mysql为什么要编译安装_Mysql编译安装
- mt6765和骁龙665哪个好_小米11正式发布,首发骁龙888+白送快充头,售价3999起
- php文件写入生成文件,PHP 文件操作类(创建文件并写入) 生成日志
- 用c++来开发php的底层模块|用c++来开发apache模块,Apache模块开发实例(2)
- php框架 css文件引用,yii框架中怎么引入css文件
- 英语在线听力翻译器_仁爱版初一英语免费听力训练电子教程
- java中valueof_Java中String.valueOf()方法的解释