open-cv 6-10节

第六节 图像的拼接  

import cv2
import numpy as np

def stackImages(scale,imgArray):
    rows = len(imgArray)#
   
cols = len(imgArray[0])#
   
rowsAvailable = isinstance(imgArray[0], list)#isinstance(object实例对象, classinfo类,判断一个对象是否是一个已知的类型
   
width = imgArray[0][0].shape[1]#数组的第一行第一列的图像的宽度大小,shape[1](第一维度)表示宽度
   
height = imgArray[0][0].shape[0]#数组的第一行第一列图像的高度大小,shape[0](第二维度)表示高度
   
if rowsAvailable:#如果是列表,把每一个元素进行处理,把图片数组变成同样的大小,并生成后堆叠在一起
       
for x in range ( 0, rows):#
           
for y in range(0, cols):#
               
if imgArray[x][y].shape[:2] == imgArray[0][0].shape [:2]:
                    imgArray[x][y] = cv2.resize(imgArray[x][y], (0, 0), None, scale, scale)
                else:
                    imgArray[x][y] = cv2.resize(imgArray[x][y], (imgArray[0][0].shape[1], imgArray[0][0].shape[0]), None, scale, scale)
                if len(imgArray[x][y].shape) == 2: imgArray[x][y]= cv2.cvtColor( imgArray[x][y], cv2.COLOR_GRAY2BGR)
        imageBlank = np.zeros((height, width, 3), np.uint8)
        hor = [imageBlank]*rows
        hor_con = [imageBlank]*rows
        for x in range(0, rows):
            hor[x] = np.hstack(imgArray[x])
        ver = np.vstack(hor)
    else:
        for x in range(0, rows):
            if imgArray[x].shape[:2] == imgArray[0].shape[:2]:
                imgArray[x] = cv2.resize(imgArray[x], (0, 0), None, scale, scale)
            else:
                imgArray[x] = cv2.resize(imgArray[x], (imgArray[0].shape[1], imgArray[0].shape[0]), None,scale, scale)
            if len(imgArray[x].shape) == 2: imgArray[x] = cv2.cvtColor(imgArray[x], cv2.COLOR_GRAY2BGR)
        hor= np.hstack(imgArray)
        ver = hor
    return ver

img = cv2.imread('Resources/lena.png')
imgGray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#转变为120灰色

imgStack = stackImages(0.5,([img,imgGray,img],[img,img,img]))
#stackImages(大小比例(such:0.5),([横向图片,横向图片,···],[纵向图片,纵向图片,纵向图片····]))

# imgHor = np.hstack((img,img))#纵向并排两张图
# imgVer = np.vstack((img,img))#横向并排两张图
#
# cv2.imshow("Horizontal",imgHor)
# cv2.imshow("Vertical",imgVer)
cv2.imshow("ImageStack",imgStack)

cv2.waitKey(0)

 

 

 

 

第七节 通过滑动条动态改变图像颜色  

import cv2
import numpy as np

#定义一个空函数
def empty(a):
    pass

#引入拼接图片的函数
def stackImages(scale,imgArray):
    rows = len(imgArray)
    cols = len(imgArray[0])
    rowsAvailable = isinstance(imgArray[0], list)
    width = imgArray[0][0].shape[1]
    height = imgArray[0][0].shape[0]
    if rowsAvailable:
        for x in range ( 0, rows):
            for y in range(0, cols):
                if imgArray[x][y].shape[:2] == imgArray[0][0].shape [:2]:
                    imgArray[x][y] = cv2.resize(imgArray[x][y], (0, 0), None, scale, scale)
                else:
                    imgArray[x][y] = cv2.resize(imgArray[x][y], (imgArray[0][0].shape[1], imgArray[0][0].shape[0]), None, scale, scale)
                if len(imgArray[x][y].shape) == 2: imgArray[x][y]= cv2.cvtColor( imgArray[x][y], cv2.COLOR_GRAY2BGR)
        imageBlank = np.zeros((height, width, 3), np.uint8)
        hor = [imageBlank]*rows
        hor_con = [imageBlank]*rows
        for x in range(0, rows):
            hor[x] = np.hstack(imgArray[x])
        ver = np.vstack(hor)
    else:
        for x in range(0, rows):
            if imgArray[x].shape[:2] == imgArray[0].shape[:2]:
                imgArray[x] = cv2.resize(imgArray[x], (0, 0), None, scale, scale)
            else:
                imgArray[x] = cv2.resize(imgArray[x], (imgArray[0].shape[1], imgArray[0].shape[0]), None,scale, scale)
            if len(imgArray[x].shape) == 2: imgArray[x] = cv2.cvtColor(imgArray[x], cv2.COLOR_GRAY2BGR)
        hor= np.hstack(imgArray)
        ver = hor
    return ver



#定义滑动栏窗口
cv2.namedWindow("TrackBars")
cv2.resizeWindow("TrackBars",640,240)
#定义滑动栏 cv::createTrackbar("进度条的名称","窗口名",最大值,最小值,回调函数);
cv2.createTrackbar("Hue Min","TrackBars",0,179,empty)
cv2.createTrackbar("Hue Max","TrackBars",19,179,empty)
cv2.createTrackbar("Sat Min","TrackBars",110,255,empty)
cv2.createTrackbar("Sat Max","TrackBars",240,255,empty)
cv2.createTrackbar("Val Min","TrackBars",153,255,empty)
cv2.createTrackbar("Val Max","TrackBars",255,255,empty)

path = 'Resources/lambo.png'
while True:
    img = cv2.imread(path)

    imgHSV = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)#把颜色转变为hsv #hsv色调 饱和度 亮度  hue saturation value
   
h_min = cv2.getTrackbarPos("Hue Min","TrackBars")
    h_max = cv2.getTrackbarPos("Hue Max", "TrackBars")
    s_min = cv2.getTrackbarPos("Sat Min", "TrackBars")
    s_max = cv2.getTrackbarPos("Sat Max", "TrackBars")
    v_min = cv2.getTrackbarPos("Val Min", "TrackBars")
    v_max = cv2.getTrackbarPos("Val Max", "TrackBars")
    print(h_min,h_max,s_min,s_max,v_min,v_max)
    lower = np.array([h_min,s_min,v_min])#最小值
   
upper = np.array([h_max,s_max,v_max])#最大值
   
mask = cv2.inRange(imgHSV,lower,upper)#使用mask 遮罩来使得所需要的颜色被保留,不需要的颜色就隐藏掉。 #图像与操作,使颜色变为彩色
   
imgResult = cv2.bitwise_and(img,img,mask=mask)#cv2.bitwise_and(src1,与操作的src1, 内置参数mask=InputArray mask=noArray());
    # 二进制数据进行“与”操作,即对图像(灰度图像或彩色图像均可)每个像素值进行二进制“与”操作,



    # cv2.imshow("Original",img)
    # cv2.imshow("HSV",imgHSV)
    # cv2.imshow("Mask", mask)
    # cv2.imshow("Result", imgResult)

   
imgStack = stackImages(0.6,([img,imgHSV],[mask,imgResult]))
    cv2.imshow("Stacked Images", imgStack)

    cv2.waitKey(1)

 

 

 

 

 

第八节 获取图片的边缘、并显示边框、文字

import cv2
import numpy as np

def stackImages(scale,imgArray):
    rows = len(imgArray)
    cols = len(imgArray[0])
    rowsAvailable = isinstance(imgArray[0], list)
    width = imgArray[0][0].shape[1]
    height = imgArray[0][0].shape[0]
    if rowsAvailable:
        for x in range ( 0, rows):
            for y in range(0, cols):
                if imgArray[x][y].shape[:2] == imgArray[0][0].shape [:2]:
                    imgArray[x][y] = cv2.resize(imgArray[x][y], (0, 0), None, scale, scale)
                else:
                    imgArray[x][y] = cv2.resize(imgArray[x][y], (imgArray[0][0].shape[1], imgArray[0][0].shape[0]), None, scale, scale)
                if len(imgArray[x][y].shape) == 2: imgArray[x][y]= cv2.cvtColor( imgArray[x][y], cv2.COLOR_GRAY2BGR)
        imageBlank = np.zeros((height, width, 3), np.uint8)
        hor = [imageBlank]*rows
        hor_con = [imageBlank]*rows
        for x in range(0, rows):
            hor[x] = np.hstack(imgArray[x])
        ver = np.vstack(hor)
    else:
        for x in range(0, rows):
            if imgArray[x].shape[:2] == imgArray[0].shape[:2]:
                imgArray[x] = cv2.resize(imgArray[x], (0, 0), None, scale, scale)
            else:
                imgArray[x] = cv2.resize(imgArray[x], (imgArray[0].shape[1], imgArray[0].shape[0]), None,scale, scale)
            if len(imgArray[x].shape) == 2: imgArray[x] = cv2.cvtColor(imgArray[x], cv2.COLOR_GRAY2BGR)
        hor= np.hstack(imgArray)
        ver = hor
    return ver

def getContours(img):#定义一个获取图片边缘的函数
    #contours图片边缘、hierarchy等高线findContours(img,检索外部轮廓的方法,提供所有信息的近似值)
   
contours,hierarchy = cv2.findContours(img,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)

    #不断循环找到图片边缘,返回轮廓list
   
for cnt in contours:
        area = cv2.contourArea(cnt)#找到区域的点

        #绘制
       
print(area)
        if area>500:#防止因为环境改变区域的大小
            # drawContours("图片src","轮廓list","指定绘制轮廓list中的哪条轮廓,如果是-1,则绘制其中的所有轮廓。",颜色,线条厚度)
           
cv2.drawContours(imgContour, cnt, -1, (255, 0, 0), 3)
            #图形的每条弧长,长度近似拐角即可获得 形状。cv2.arcLength() 计算得到。arcLength(轮廓list,True)True可以用来指定对象的形状是闭合的,还是打开的先
           
peri = cv2.arcLength(cnt,True)
            #print(peri)
            #
面积计算轮廓的近似值参数说明:contour表示输入的轮廓值, length表示轮廓的大小, True表示是否闭合
           
approx = cv2.approxPolyDP(cnt,0.02*peri,True)
            print(len(approx))
            #获取图形的角个数
           
objCor = len(approx)
            #获取边界的像素、宽度、高度
           
x, y, w, h = cv2.boundingRect(approx)

            if objCor ==3: objectType ="Tri"
           
elif objCor == 4:
                aspRatio = w/float(h)#高度宽度的比
               
if aspRatio >0.98 and aspRatio <1.03: objectType= "Square"#正方形
               
else:objectType="Rectangle"#长方形
           
elif objCor>4: objectType= "Circles"#圆形
           
else:objectType="None"

           
cv2.rectangle(imgContour,(x,y),(x+w,y+h),(0,255,0),2)#画圆(img.(起点),(终点),(RGB 颜色)(线条的宽度))
           
cv2.putText(imgContour,objectType,
                        (x+(w//2)-10,y+(h//2)-10),cv2.FONT_HERSHEY_COMPLEX,0.7,
                        (0,0,0),2)#写文字
#================================================================================================#
path = 'Resources/shapes.png'
img = cv2.imread(path)
imgContour = img.copy()

imgGray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
imgBlur = cv2.GaussianBlur(imgGray,(7,7),1)
imgCanny = cv2.Canny(imgBlur,50,50)#边缘检测器,连接线条,(src,不知道是什么,值越大线条越少)
getContours(imgCanny)#调用方法

imgBlank = np.zeros_like(img)#空白图片
imgStack = stackImages(0.7,([img,imgGray,imgBlur],
                            [imgCanny,imgContour,imgBlank]))

cv2.imshow("Stack", imgStack)

cv2.waitKey(0)

 

 

第九节 识别canny的脸  

import cv2

#加载目标检测的级联分类器的类
faceCascade= cv2.CascadeClassifier("Resources/haarcascade_frontalface_default.xml")
img = cv2.imread('Resources/lena.png')
imgGray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#转变为灰色

faces = faceCascade.detectMultiScale(imgGray,1.1,4)#detectMultiScale(img,搜索前后两次窗口大小比例,相邻矩阵最小个数)

#围绕面部创建边框
for (x,y,w,h) in faces:
    cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)#(img.(起点),(终点),(RGB 颜色)(线条的宽度))

cv2.imshow("Result", img)
cv2.waitKey(0)

#实现多尺度检测g_cascade.detectMultiScale(InputArray image,   //输入图像
#CV_OUT std::vector<Rect>& objects,    //输出检测到的目标区域
#        double scaleFactor =1.1,         //搜索前后两次窗口大小比例系数,默认1.1,即每次搜索窗口扩大10%
##       int minNeighbors = 3,           //构成检测目标的相邻矩形的最小个数 如果组成检测目标的小矩形的个数和小于minneighbors - 1 都会被排除,如果minneighbors为0 则函数不做任何操作就返回所有被检候选矩形框
#        int flags = 0,                //若设置为CV_HAAR_DO_CANNY_PRUNING 函数将会使用Canny边缘检测来排除边缘过多或过少的区域
#        Size minSize = Size(),          //能检测的最小尺寸
#        Size maxSize = Size()           //能检测的最大尺寸
#        );
#

 

 

 

 

第十节 给笔尖加颜色

import cv2
import numpy as np

frameWidth = 640
frameHeight = 480
cap = cv2.VideoCapture(0)
cap.set(3, frameWidth)
cap.set(4, frameHeight)
cap.set(10,150)     #1.亮度

#myColors = [[160,124,110,179,255,255]]
#myColorValues = [[0,0,255]]

myColors = [[48,112,109,179,255,255],#蓝色
           
[133,56,0,159,156,255],#蓝色
           
[57,76,0,100,255,255],#紫色
           
[90,48,0,118,255,255]]#绿色
myColorValues = [[51,153,255],   #橙色       ## BGR
                
[255,0,255],    #紫色
                
[0,255,0],     #绿色
                
[255,0,0]]
#4.定义计数器的列表
myPoints =  []  ## [x , y , colorId ]

def findColor(img,myColors,myColorValues):#2.定义检测颜色函数
   
imgHSV = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)#颜色转变为hsv
   
count = 0
    newPoints=[]#清空
   
for color in myColors:
        lower = np.array(color[0:3])#for魂环,第一次遍历第一行的1-3列,第二次遍历第一行的1-3列
       
upper = np.array(color[3:6])#for魂环,第一次遍历第一行的3-6列,第二次遍历第一行的3-6列
       
mask = cv2.inRange(imgHSV,lower,upper)#使用mask 遮罩来使得所需要的颜色被保留,不需要的颜色就隐藏掉。 #图像与操作,使颜色变为彩色
#3.调用函数
       
x,y=getContours(mask)
        cv2.circle(imgResult,(x,y),2,myColorValues[count],cv2.FILLED)#3.画圆圈(img.(中心点),(半径),(RGB 颜色)(线条的宽度))
#4.定义计数器
       
if x!=0 and y!=0:#4.
           
newPoints.append([x,y,count])
        count +=1
        #cv2.imshow(str(color[0]),mask)#字符串矩阵
#6.返回newPoints【x,y,count】
   
return newPoints
#3.给笔尖加颜色
def getContours(img):
    contours,hierarchy = cv2.findContours(img,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
    x,y,w,h = 0,0,0,0
    for cnt in contours:
        area = cv2.contourArea(cnt)
        if area>500:#3.防止因为环境改变区域的大小
            #cv2.drawContours(imgResult, cnt, -1, (255, 0, 0), 3) # drawContours("图片src","轮廓list","指定绘制轮廓list中的哪条轮廓,如果是-1,则绘制其中的所有轮廓。",颜色,线条厚度)
           
peri = cv2.arcLength(cnt,True)#图形的每条弧长,长度近似拐角即可获得 形状。cv2.arcLength() 计算得到。arcLength(轮廓list,True)True可以用来指定对象的形状是闭合的,还是打开的先
           
approx = cv2.approxPolyDP(cnt,0.02*peri,True) #面积计算轮廓的近似值参数说明:contour表示输入的轮廓值, length表示轮廓的大小, True表示是否闭合
           
x, y, w, h = cv2.boundingRect(approx)   #获取边界的像素、宽度、高度
   
return x+w//2,y

#5给检测的笔尖画圆圈
def drawOnCanvas(myPoints,myColorValues):
    for point in myPoints:
        #6画圆
       
cv2.circle(imgResult, (point[0], point[1]), 5, myColorValues[point[2]], cv2.FILLED)#画圆圈(img.(中心点),(半径),(RGB 颜色)(线条的宽度))

while True:
    success, img = cap.read() #1.读取提视频
   
imgResult = img.copy()
#4.计数器,返回x,y,count
   
newPoints = findColor(img, myColors,myColorValues)
    if len(newPoints)!=0:
        for newP in newPoints:
            myPoints.append(newP)
    if len(myPoints)!=0:
# 6画圆
       
drawOnCanvas(myPoints,myColorValues)


    cv2.imshow("Result", imgResult)  #1.显示结果
   
if cv2.waitKey(1) & 0xFF == ord('q'): #获取键盘输入
       
break;

 

 

 

 

posted @ 2020-11-30 09:39  码农浩  阅读(145)  评论(0)    收藏  举报