博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
OpenCV-图像轮廊二
阅读量:2051 次
发布时间:2019-04-28

本文共 9426 字,大约阅读时间需要 31 分钟。

图像轮廊二

凸包

逼近多边形是轮廊的高度相似,但是有时候,我们希望使用一个多边形的凸包来简化它,凸包跟逼近多边形很相似,只不过它是物体最外层的“凸”多边形。凸包指的是完全包含原有轮廊,并且仅有轮廊上的点所构成的多边形。凸包的每一处都是凸的,即在凸包内连接任意两点的直线都在凸包的内部。在凸包内,任意连接三个点的内角小于180°

1.使用cv2.convexHull()函数,实现图像轮廓凸包的获取。
2.使用cv2.polylines()函数,实现图像轮廓凸包的绘制。

凸包的绘制

cv2.polylines(src, [points], isClosed,color, thickness)

src:要处理的图像。

points:点集。
isClosed:布尔型,True表示的是线段闭合,False表示的是仅保留线段。
color:线段颜色,格式是(B,G,R)值。
thickness:数值型,厚度,默认值为1,如果对封闭图形,正方形,三角形等传入-1,则会填充整个图形。

import cv2img = cv2.imread('contours2.png', 1)gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)ret, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)contours, hierarchy = cv2.findContours(binary,cv2.RETR_LIST,cv2.CHAIN_APPROX_NONE)cnt = contours[0]hull = cv2.convexHull(cnt)cv2.polylines(img,[hull],True,(255,0,0),2)cv2.imshow('line', img)cv2.waitKey()cv2.destroyAllWindows()

在这里插入图片描述

实物凸包检测

import cv2img = cv2.imread('hand.png', 1)gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)ret, binary = cv2.threshold(gray, 60, 255, cv2.THRESH_BINARY)contours, hierarchy = cv2.findContours(binary,cv2.RETR_LIST,cv2.CHAIN_APPROX_NONE)n=len(contours)    contoursImg=[]x=0 for i in range(n):    area = cv2.contourArea(contours[i])    if area>10000:            print(f"轮廓{i}的面积:\n{area}")        x=icnt = contours[x]cv2.imshow("binary",binary)hull = cv2.convexHull(cnt)cv2.polylines(img,[hull],True,(0,255,0),2)cv2.drawContours(img,contours,x,(0,0,255), 3)#显示图片cv2.imshow('line', img)cv2.waitKey(0)cv2.destroyAllWindows()

在这里插入图片描述

凸缺陷的概念

凸包与轮廓之间的部分,称为凸缺陷。轮廓上距离这条线最远的

点就是凸缺陷的点。

convexityDefects = cv2.convexityDefects(contour, convexhull)

contour:轮廓。

convexhull:凸包.

import cv2o = cv2.imread('contours2.png') gray = cv2.cvtColor(o,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)cnt = contours[0]hull = cv2.convexHull(cnt,returnPoints = False)            defects = cv2.convexityDefects(cnt,hull)         for i in range(defects.shape[0]):    s,e,f,d = defects[i,0]         start = tuple(cnt[s][0])           # 得到的是索引,要再轮廓中选出来    end = tuple(cnt[e][0])    far = tuple(cnt[f][0])    cv2.line(o,start,end,[0,0,255],2)    cv2.circle(o,far,5,[255,0,0],-1)cv2.imshow('result',o)cv2.waitKey(0)cv2.destroyAllWindows()

在这里插入图片描述

实物凸缺陷检测

import cv2import numpy as npimg = cv2.imread('hand.png') blur=cv2.medianBlur(img,5)gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) ret, binary = cv2.threshold(gray,60,255,cv2.THRESH_BINARY) contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)n=len(contours)       contoursImg=[]x=0 for i in range(n):    area = cv2.contourArea(contours[i])    if area>10000:            print(f"轮廓{i}的面积:\n{area}")        x=icnt = contours[x]hull = cv2.convexHull(cnt,returnPoints = False)            defects = cv2.convexityDefects(cnt,hull)         #print(defects)for i in range(defects.shape[0]):    s,e,f,d = defects[i,0]      #print(s,e,f,d)    start = tuple(cnt[s][0])              end = tuple(cnt[e][0])    far = tuple(cnt[f][0])    #print(far ,end)    cv2.line(img,start,end,[0,0,255],2)    cv2.circle(img,far,5,[255,0,0],-1)cv2.imshow('result',img)cv2.waitKey(0)cv2.destroyAllWindows()

在这里插入图片描述

宽高比

可以使用宽高比(AspectRation)来描述轮廓,例如矩形轮廓的宽高比为:

宽高比=宽度(Width)/高度(Height)

import cv2o = cv2.imread('binaryhand.png')  cv2.imshow("original",o)gray = cv2.cvtColor(o,cv2.COLOR_BGR2GRAY)  ret, binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)  contours, hierarchy = cv2.findContours(binary,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)  x,y,w,h = cv2.boundingRect(contours[0])cv2.rectangle(o,(x,y),(x+w,y+h),(255,255,255),3)aspectRatio = float(w)/hprint(aspectRatio)cv2.imshow("result",o)cv2.waitKey()cv2.destroyAllWindows()

在这里插入图片描述

Extent

可以使用轮廓面积与矩形边界(矩形包围框、矩形轮廓)面积之比Extend来描述图像及其轮廓特征。计算方法为:

Extend =轮廓面积/矩形边界面积

import cv2o = cv2.imread('binaryhand.png')  cv2.imshow("original",o)gray = cv2.cvtColor(o,cv2.COLOR_BGR2GRAY)  ret, binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)  contours, hierarchy = cv2.findContours(binary,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)  x,y,w,h = cv2.boundingRect(contours[0])cv2.drawContours(o,contours[0],-1,(0,0,255),3) cv2.rectangle(o,(x,y),(x+w,y+h),(255,0,0),3)rectArea=w*hcntArea=cv2.contourArea(contours[0])extend=float(cntArea)/rectAreaprint(extend)cv2.imshow("result",o)cv2.waitKey()cv2.destroyAllWindows()

在这里插入图片描述

最大值和最小值及它们的位置

OpenCV提供了函数cv2.minMaxLoc(),用于在指定的对象内查找最大值、最小值及其位置。该函数的语法格式是:

min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(imgray, mask = mask)

min_val:最小值。

max_val:最大值。
min_loc:最小值的位置。
max_loc:最大值的位置。
OpenCV提供了函数cv2.mean(),用于计算一个对象的平均颜色或
平均灰度。该函数的语法格式为:
mean_val = cv2.mean(im, mask = mask)
im:原图像。
mask:掩模。

import cv2import numpy as npo = cv2.imread('ct2.jpg')  cv2.imshow("original",o)gray = cv2.cvtColor(o,cv2.COLOR_BGR2GRAY)  ret, binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)  contours, hierarchy = cv2.findContours(binary,                                             cv2.RETR_LIST,                                             cv2.CHAIN_APPROX_SIMPLE)  cnt=contours[3]  mask = np.zeros(gray.shape,np.uint8)mask=cv2.drawContours(mask,[cnt],-1,255,-1)   minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(gray,mask = mask)print("minVal=",minVal)print("maxVal=",maxVal)print("minLoc=",minLoc)print("maxLoc=",maxLoc)masko = np.zeros(o.shape,np.uint8)masko=cv2.drawContours(masko,[cnt],-1,(255,255,255),-1)loc=cv2.bitwise_and(o,masko) cv2.imshow("mask",loc)#显示灰度结果#loc=cv2.bitwise_and(gray,mask) #cv2.imshow("mask",loc)cv2.destroyAllWindows()

在这里插入图片描述

平均颜色及平均灰度

meanVal = cv2.mean(o,mask = mask)  #mask是区域,所以必须是单通道的print("meanVal=\n",meanVal)

极点

有时,我们希望获取某个对象内的极值点,例如最左端、最右端、

最上端、最下端的四个点。OpenCV提供了相应的函数来找出这些
点,通常的语法格式是:

leftmost = tuple(cnt[cnt[:, :,0].argmin()][0])    rightmost = tuple(cnt[cnt[:, :,0].argmax()][0])    topmost = tuple(cnt[cnt[:, :,1].argmin()][0])    bottommost = tuple(cnt[cnt[:, :,1].argmax()][0])
import cv2import numpy as npo = cv2.imread('binaryhand.png')  o1 = cv2.imread("face.png")o1 = cv2.resize(o1,(40,40))gray = cv2.cvtColor(o,cv2.COLOR_BGR2GRAY)  ret, binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)  contours, hierarchy = cv2.findContours(binary,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)  mask = np.zeros(gray.shape,np.uint8)cnt=contours[0] cv2.drawContours(mask,[cnt],0,255,-1)leftmost = tuple(cnt[cnt[:,:,0].argmin()][0])rightmost = tuple(cnt[cnt[:,:,0].argmax()][0])topmost = tuple(cnt[cnt[:,:,1].argmin()][0])bottommost = tuple(cnt[cnt[:,:,1].argmax()][0])print("leftmost=",leftmost)print("rightmost=",rightmost)print("topmost=",topmost)print("bottommost=",bottommost)font=cv2.FONT_HERSHEY_SIMPLEXcv2.putText(o,'A',leftmost, font, 1,(0,0,255),2)o[284:324,229:269]=o1cv2.putText(o,'B',rightmost, font, 1,(0,0,255),2)cv2.putText(o,'C',topmost, font, 1,(0,0,255),2)cv2.putText(o,'D',bottommost, font, 1,(0,0,255),2)cv2.imshow("result",o)cv2.waitKey()cv2.destroyAllWindows()

在这里插入图片描述

轮廓特征值的应用场景

import cv2import numpy as npimg = cv2.imread('face.png')  cv2.imshow("original",img)gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)  ret, binary = cv2.threshold(gray,0,255,cv2.THRESH_BINARY)  contours, hierarchy = cv2.findContours(binary,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)  h,w,c=img.shapemask = np.zeros((h,w,c),np.uint8)for cnt in contours:        x,y,w,h = cv2.boundingRect(cnt)    cv2.rectangle(img,(x,y),(x+w,y+h),(255,255,255),3)    ratio = float(w)/h    if ratio<1:        cv2.drawContours(mask,[cnt],-1,(0,0,255), -1)        #n+=1        print(ratio,"是长的椭圆")    else:        cv2.drawContours(mask,[cnt],-1,(0,255,255), -1)        #n+=1        print(ratio,"是扁的椭圆")cv2.imshow("result",mask)cv2.waitKey()cv2.destroyAllWindows()

在这里插入图片描述

import cv2import numpy as npimg = cv2.imread('face.png')  cv2.imshow("original",img)gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)  ret, binary = cv2.threshold(gray,0,255,cv2.THRESH_BINARY)  contours, hierarchy = cv2.findContours(binary,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)  h,w,c=img.shapemask = np.zeros((h,w,c),np.uint8)for cnt in contours:        x,y,w,h = cv2.boundingRect(cnt)    cv2.rectangle(img,(x,y),(x+w,y+h),(255,255,255),3)    ratio = float(w)/h    rectArea=w*h    cntArea=cv2.contourArea(contours[0])    extend=float(cntArea)/rectArea    print(extend)        if ratio<1:        cv2.drawContours(mask,[cnt],-1,(0,0,255), -1)        print(ratio,"是长的椭圆")    else:        cv2.drawContours(mask,[cnt],-1,(0,255,255), -1)        print(ratio,"是扁的椭圆")    if extend==0.9818696450428397:        cv2.drawContours(mask,[cnt],-1,(255,0,255), -1)        cv2.imshow("result",mask)cv2.waitKey()cv2.destroyAllWindows()

在这里插入图片描述

计数

import cv2import numpy as npimg = cv2.imread('face.png')  cv2.imshow("original",img)gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)  ret, binary = cv2.threshold(gray,0,255,cv2.THRESH_BINARY)  contours, hierarchy = cv2.findContours(binary,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)  h,w,c=img.shapemask = np.zeros((h,w,c),np.uint8)n1,n2,n3=0,0,0for cnt in contours:        x,y,w,h = cv2.boundingRect(cnt)    cv2.rectangle(img,(x,y),(x+w,y+h),(255,255,255),3)    ratio = float(w)/h    rectArea=w*h    cntArea=cv2.contourArea(contours[0])    extend=float(cntArea)/rectArea    print(extend)        if extend==0.9818696450428397:        n1+=1        cv2.drawContours(mask,[cnt],-1,(255,0,0), -1)    elif ratio<1 and extend!=0.9818696450428397:        cv2.drawContours(mask,[cnt],-1,(0,0,255), -1)        n2+=1    else:        cv2.drawContours(mask,[cnt],-1,(0,255,255), -1)        n3+=1print(f"有{n1}个矩形,有{n2}个长的椭圆,有{n3}个扁的椭圆")cv2.imshow("result",mask)cv2.waitKey()cv2.destroyAllWindows()

在这里插入图片描述

转载地址:http://clklf.baihongyu.com/

你可能感兴趣的文章
深入分析JavaWeb技术内幕(一)—— 深入Web请求过程
查看>>
深入分析JavaWeb技术内幕(二)—— 深入分析Java I/O的工作机制
查看>>
使用Java将PDF解析成HTML页面进行展示并从页面中提取Json数据设置到Table中
查看>>
Redis学习笔记(五)—— 在Linux下搭建Redis集群
查看>>
Redis学习笔记(六)—— 解决安装ruby出现的问题:redis requires Ruby version &amp;gt;= 2.2.2.
查看>>
从原理上搞懂编码——究竟什么是编码?什么是解码?什么是字节流?
查看>>
前端上传文件组件Plupload使用指南
查看>>
单点登录原理与简单实现
查看>>
使用zxing生成彩色或带图片的二维码
查看>>
在Linux下安装JDK8
查看>>
面试题 —— HTTP请求中get请求和post请求的区别以及底层原理
查看>>
面试题 —— HashMap、HashTable、HashSet的实现原理和底层数据结构
查看>>
C语言学习笔记(三)—— 数据和C
查看>>
Java编程思想(三)—— 操作符
查看>>
梦飞 —— 述:我只是一个普通农民家的孩子,但我有一个梦想
查看>>
图解HTTP(二)—— 简单的HTTP协议
查看>>
程序员的数学(四)—— 数学归纳法,如何征服无穷数列
查看>>
不是技术人员也能看懂云计算、大数据、人工智能
查看>>
图解HTTP(三)—— HTTP报文内的HTTP信息
查看>>
图解HTTP(四)—— 返回结果的HTTP状态码
查看>>