翻译原文 转换完成,然后是分析,然后是任何覆盖 img = cv2.imread(‘watch.jpg’,cv2.IMREAD_GRAYSCALE) cv2.imshow(‘image’,img) cv2.waitKey(0) cv2.destroyAllWindows()
plt.imshow(img, cmap = ‘gray’, interpolation = ‘bicubic’) plt.xticks([]), plt.yticks([])
to hide tick values on X and Y
axisplt.plot([200,300,400],[100,200,300],‘c’, linewidth=5) plt.show()
cv2.imwrite(‘watchgray.png’,img) 二、加载视频源 cap = cv2.VideoCapture(0) while(True): ret, frame = cap.read() ret是一个代表是否有返回的布尔值,frame是每个返回的帧。 如果没有帧,你不会得到错误,你会得到None。 gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) cv2.imshow(‘frame’,gray) if cv2.waitKey(1) & 0xFF == ord(‘q’): 这个语句每帧只运行一次。 基本上,如果我们得到一个按键,那个键是q,我们将退出while循环,然后运行: break cap.release() cv2.destroyAllWindows()
cap = cv2.VideoCapture(1) fourcc = cv2.VideoWriter_fourcc(*‘XVID’) out = cv2.VideoWriter(‘output.avi’,fourcc, 20.0, (640,480)) while(True): ret, frame = cap.read() gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) out.write(frame) cv2.imshow(‘frame’,gray) if cv2.waitKey(1) & 0xFF == ord(‘q’): break cap.release() out.release() cv2.destroyAllWindows() 图像绘制 cv2.line(img,(0,0),(150,150),(255,255,255),15) cv2.rectangle(img,(15,25),(200,150),(0,0,255),15) cv2.circle(img,(100,63), 55, (0,255,0), -1)
四、图像操作 px = img[55,55] print(px) 引用 ROI,图像区域: px = img[100:150,100:150] print(px) 我们可以引用我们的图像的特定特征: print(img.shape) print(img.size) print(img.dtype)
五、图像算术和逻辑运算 img1 = cv2.imread(‘3D-Matplotlib.png’) img2 = cv2.imread(‘mainsvmimage.png’) add = img1+img2 cv2.imshow(‘add’,add) cv2.waitKey(0) cv2.destroyAllWindows()
add = cv2.add(img1,img2) weighted = cv2.addWeighted(img1, 0.6, img2, 0.4, 0) img1 = cv2.imread(‘3D-Matplotlib.png’) img2 = cv2.imread(‘mainlogo.png’)
I want to put logo on top-left corner, So I create a ROI
rows,cols,channels = img2.shape roi = img1[0:rows, 0:cols ]
Now create a mask of logo and create its inverse
maskimg2gray = cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)
add a threshold
ret, mask = cv2.threshold(img2gray, 220, 255, cv2.THRESH_BINARY_INV) 在第一个图像中将这个区域遮住,然后将空白区域替换为图像 2 的内容。 mask_inv = cv2.bitwise_not(mask)
Now black-out the area of logo in ROI
img1_bg = cv2.bitwise_and(roi,roi,mask = mask_inv)
Take only region of logo from logo
image.img2_fg = cv2.bitwise_and(img2,img2,mask = mask) dst = cv2.add(img1_bg,img2_fg) img1[0:rows, 0:cols ] = dst cv2.imshow(‘res’,img1 )cv2.waitKey(0) cv2.destroyAllWindows()
六、阈值 retval, threshold = cv2.threshold(img, 10, 255, cv2.THRESH_BINARY) 因为这是低光照的图片,所以我们选择低的数字。 通常 125-150 左右的东西可能效果最好。 grayscaled = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) retval, threshold = cv2.threshold(grayscaled, 10, 255, cv2.THRESH_BINARY) cv2.imshow(‘original’,img)cv2.imshow(‘threshold’,threshold) cv2.waitKey(0) cv2.destroyAllWindows()
但是我们仍然在这里忽略了很多背景。 接下来,我们可以尝试自适应阈值,这将尝试改变阈值,并希望弄清楚弯曲的页面 th = cv2.adaptiveThreshold(grayscaled, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 115, 1) cv2.imshow(‘original’,img) cv2.imshow(‘Adaptive threshold’,th)
七、颜色过滤 将你的颜色转换为 HSV,即“色调饱和度纯度” ,这可以帮助你根据色调和饱和度范围,使用变化的值确定一个更具体的颜色。 cap = cv2.VideoCapture(0) while(1): _, frame = cap.read() hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) 首先要把帧转换成 HSV lower_red = np.array([30,150,50]) upper_red = np.array([255,255,180]) mask = cv2.inRange(hsv, lower_red, upper_red) 我们使用inRange函数,为我们的特定范围创建掩码。 res = cv2.bitwise_and(frame,frame, mask= mask) 通过执行按位操作来“恢复”我们的红色 cv2.imshow(‘frame’,frame) cv2.imshow(‘mask’,mask) cv2.imshow(‘res’,res) k = cv2.waitKey(5) & 0xFF if k == 27: break cv2.destroyAllWindows() cap.release() 典型的红色仍然会有一些绿色和蓝色分量,所以我们必须允许一些绿色和蓝色,但是我们会想要几乎全红。 这意味着我们会在这里获得所有颜色的低光混合。 我们在这里还是有一些“噪音”。东西有颗粒感,红色中的黑点很多,还有许多其他的小色点。我们可以做一些事情,试图通过模糊和平滑来缓解这个问题
八、模糊和平滑 过滤器中消除噪声,例如简单的阈值,或者甚至我们以前的特定的颜色过滤器 kernel = np.ones((15,15),np.float32)/225 smoothed = cv2.filter2D(res,-1,kernel) cv2.imshow(‘Original’,frame) cv2.imshow(‘Averaging’,smoothed k = cv2.waitKey(5) & 0xFF if k == 27: break cv2.destroyAllWindows() cap.release() 这个很简单,但是结果牺牲了很多粒度。 接下来,让我们尝试一些高斯模糊: blur = cv2.GaussianBlur(res,(15,15),0) cv2.imshow(‘Gaussian Blurring’,blur) 另一个选项是中值模糊: median = cv2.medianBlur(res,15) cv2.imshow(‘Median Blur’,median) 最后一个选项是双向模糊: bilateral = cv2.bilateralFilter(res,15,75,75) cv2.imshow(‘bilateral Blur’,bilateral)
九、形态变换 腐蚀是我们将“腐蚀”边缘。 它的工作方式是使用滑块(核)。 我们让滑块滑动,如果所有的像素是白色的,那么我们得到白色,否则是黑色。 这可能有助于消除一些白色噪音。 另一个版本是膨胀,它基本上是相反的:让滑块滑动,如果整个区域不是黑色的,就会转换成白色。 这是一个例子: cap = cv2.VideoCapture(0) while(1): _, frame = cap.read() hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) lower_red = np.array([30,150,50]) upper_red = np.array([255,255,180]) mask = cv2.inRange(hsv, lower_red, upper_red) res = cv2.bitwise_and(frame,frame, mask= mask) kernel = np.ones((5,5),np.uint8) erosion = cv2.erode(mask,kernel,iterations = 1) dilation = cv2.dilate(mask,kernel,iterations = 1) cv2.imshow(‘Original’,frame) cv2.imshow(‘Mask’,mask) cv2.imshow(‘Erosion’,erosion) cv2.imshow(‘Dilation’,dilation) k = cv2.waitKey(5) & 0xFF if k == 27: breakcv2. destroyAllWindows() cap.release()
下一对是“开放”和“关闭”。 开放的目标是消除“假阳性”。 有时在背景中,你会得到一些像素“噪音”。 “关闭”的想法是消除假阴性。 基本上就是你检测了你的形状,例如我们的帽子,但物体仍然有一些黑色像素。 关闭将尝试清除它们。 opening = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel) closing = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)
两个选项是tophat和blackhat,
It is the difference between input image and Opening of the image
cv2.imshow(‘Tophat’,tophat)
It is the difference between the closing of the input image and input
image. cv2.imshow(‘Blackhat’,blackhat)
十、边缘检测和渐变 图像渐变可以用来测量方向的强度,边缘检测 laplacian = cv2.Laplacian(frame,cv2.CV_64F) sobelx = cv2.Sobel(frame,cv2.CV_64F,1,0,ksize=5) sobely = cv2.Sobel(frame,cv2.CV_64F,0,1,ksize=5)
虽然我们可以使用这些渐变转换为纯边缘,但我们也可以使用 Canny 边缘检测! edges = cv2.Canny(frame,100,200) 注意阴影导致了边缘被检测到。 其中最明显的是蓝狗窝发出的阴影。
十一、模板匹配 给出一定的阈值,找到匹配我们提供的模板图像的相同区域 我们确实要选择一个阈值,其中某种东西可能是 80% 匹配,那么我们说这就匹配。 所以,我们将开始加载和转换图像: img_rgb = cv2.imread(‘opencv-template-matching-python-tutorial.jpg’) img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY) template = cv2.imread(‘opencv-template-for-matching.jpg’,0) w, h = template.shape[::-1] 对于主要图像,我们只有彩色版本和灰度版本。 我们加载模板并记下尺寸。 res = cv2.matchTemplate(img_gray,template,cv2.TM_CCOEFF_NORMED) 在这里,我们用img_gray(我们的主图像),模板和我们要使用的匹配方法, 调用matchTemplate,并将返回值称为res。 threshold = 0.8 我们指定一个阈值,这里是 80%。 loc = np.where( res >= threshold) 然后我们使用逻辑语句,找到res大于或等于 80% 的位置。
最后,我们使用灰度图像中找到的坐标,标记原始图像上的所有匹配: for pt in zip(*loc[::-1]): cv2.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0,255,255), 2) cv2.imshow(‘Detected’,img_rgb)
十二、GrabCut 前景提取 找到前景,并删除背景。 这很像绿屏 img = cv2.imread(‘opencv-python-foreground-extraction-tutorial.jpg’) mask = np.zeros(img.shape[:2],np.uint8) bgdModel = np.zeros((1,65),np.float64) fgdModel = np.zeros((1,65),np.float64) 然后我们加载图像,创建一个掩码,指定算法内部使用的背景和前景模型。 rect = (161,79,150,150) 真正重要的部分是我们定义的矩形。 这是rect = (start_x, start_y, width, height)。
cv2.grabCut(img,mask,rect,bgdModel,fgdModel,5,cv2.GC_INIT_WITH_RECT) 输入图像,然后是掩码,然后是主要对象的矩形,背景模型,前景模型,要运行的迭代量以及使用的模式。 mask2 = np.where((mask2)|(mask0),0,1).astype(‘uint8’) 改变了掩码,使得所有像素 0 和 2 转换为背景,而像素 1 和 3 现在是前景。 img = img*mask2[:,:,np.newaxis] plt.imshow(img) plt.colorbar() plt.show()
十三、角点检测 img = cv2.imread(‘opencv-corner-detection-sample.jpg’) gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) gray = np.float32(gray) corners = cv2.goodFeaturesToTrack(gray, 100, 0.01, 10) 参数是图像,检测到的最大角点数量,品质和角点之间的最小距离。 corners = np.int0(corners)
如前所述,我们在这里的锯齿问题将允许找到许多角点,所以我们对其进行了限制。 下面: for corner in corners: x,y = corner.ravel() cv2.circle(img,(x,y),3,255,-1) 现在我们遍历每个角点,在我们认为是角点的每个点上画一个圆。 cv2.imshow
十四、特征匹配(单映射)暴力 在这里,我们的模板图像在模板中,比在我们要搜索的图像中要小一些。 它的旋转也不同,阴影也有些不同。 现在我们将使用一种“暴力”匹配的形式。 我们将在这两个图像中找到所有特征。 然后我们匹配这些特征。 然后,我们可以绘制我们想要的,尽可能多的匹配。 但是要小心。 如果你绘制 500 个匹配,你会有很多误报。 所以只绘制绘制前几个。 img1 = cv2.imread(‘opencv-feature-matching-template.jpg’,0) img2 = cv2.imread(‘opencv-feature-matching-image.jpg’,0) 用于特征的检测器 orb = cv2.ORB_create() 使用orb探测器找到关键点和他们的描述符。 kp1, des1 = orb.detectAndCompute(img1,None) kp2, des2 = orb.detectAndCompute(img2,None) BFMatcher对象 bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True) 创建描述符的匹配,然后根据它们的距离对它们排序 img3 = cv2.drawMatches(img1,kp1,img2,kp2,matches[:10],None, flags=2) plt.imshow(img3) plt.show()
十五、MOG 背景减弱 如何通过检测运动来减弱图像的背景 有两个图像,一个没有你想要追踪的人物/物体,另一个拥有人物/物体 cap = cv2.VideoCapture(‘people-walking.mp4’) fgbg = cv2.createBackgroundSubtractorMOG2() while(1): ret, frame = cap.read() fgmask = fgbg.apply(frame) cv2.imshow(‘fgmask’,frame) cv2.imshow(‘frame’,fgmask) k = cv2.waitKey(30) & 0xff if k == 27: break cap.release() cv2.destroyAllWindows() 想法是从静态背景中提取移动的前景。 你也可以使用这个来比较两个相似的图像,并立即提取它们之间的差异
十六、Haar Cascade 面部检测 讨论 Haar Cascades 对象检测。我们将从脸部和眼睛检测来开始。为了使用层叠文件进行对象识别/检测,首先需要层叠文件 从导入cv2和numpy开始,然后加载我们的脸部和眼部的层叠 while 1: ret, img = cap.read() gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) faces = face_cascade.detectMultiScale(gray, 1.3, 5) 下一步就是先去拆分面部,然后才能到达眼睛 for (x,y,w,h) in faces: cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2) roi_gray = gray[y:y+h, x:x+w] roi_color = img[y:y+h, x:x+w] 我们找到了面部,它们的大小,绘制矩形,并注意 ROI 接下来,我们找了一些眼睛: eyes = eye_cascade.detectMultiScale(roi_gray) for (ex,ey,ew,eh) in eyes: cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)
|