• 肤色阈值分割


    1.视频帧读取图像(YCbCr+Ostu滤波)

    # -*- coding: utf-8 -*-
    """
    Created on Mon Dec 10 11:31:43 2018
    
    @author: 1
    """
    import cv2
    
    cap = cv2.VideoCapture(0)
    cap.set(3,640)
    cap.set(4,480)
    #调整参数实现读取视频或调用摄像头
    while(cap.isOpened()):
        ret_flag , Vshow = cap.read()#Vshow是一个三维矩阵
    #        gray = cv2.cvtColor(Vshow,cv2.COLOR_BGR2GRAY)
    #        cv2.imshow("Gray",gray)
        cv2.imshow("Capture_Test",Vshow)  #窗口显示,显示名为 Capture_Test
        k = cv2.waitKey(1) & 0xFF #每帧数据延时 1ms,延时不能为 0,否则读取的结果会是静态帧
        if  k == ord('s'):  #若检测到按键 ‘s’,打印字符串
             #显示图片分辨率
    #            print(cap.get(3));
    #            print(cap.get(4));
    #                img= cv2.cvtColor(Vshow,cv2.COLOR_BGR2GRAY)
            
    #        #肤色分割
    ##                img = cv2.imread('YCbCr OR.jpg', cv2.IMREAD_COLOR)
    #        ycrcb = cv2.cvtColor(Vshow, cv2.COLOR_BGR2YCrCb) # 把图像转换到YUV色域
    #        (y, cr, cb) = cv2.split(ycrcb) # 图像分割, 分别获取y, cr, br通道图像
    #        # 高斯滤波, cr 是待滤波的源图像数据, (5,5)是值窗口大小, 0 是指根据窗口大小来计算高斯函数标准差
    #        cr1 = cv2.GaussianBlur(cr, (5, 5), 0) # 对cr通道分量进行高斯滤波
    #        # 根据OTSU算法求图像阈值, 对图像进行二值化
    #        #_, skin1 = cv2.threshold(cr1, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) 
    #        _, img = cv2.threshold(cr1, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
    #        #cv2.imshow("image CR", cr1)
    ##                cv2.imshow("Skin Cr+OSTU", skin )
            
            cv2.imwrite("test.jpg",Vshow)
            # 肤色检测之一: YCrCb之Cr分量 + OTSU二值化
            img = cv2.imread('test.jpg', cv2.IMREAD_COLOR)
            ycrcb = cv2.cvtColor(img, cv2.COLOR_BGR2YCrCb) # 把图像转换到YUV色域
            (y, cr, cb) = cv2.split(ycrcb) # 图像分割s, 分别获取y, cr, br通道图像
            # 高斯滤波, cr 是待滤波的源图像数据, (5,5)是值窗口大小, 0 是指根据窗口大小来计算高斯函数标准差
            cr1 = cv2.GaussianBlur(cr, (5, 5), 0) # 对cr通道分量进行高斯滤波
            # 根据OTSU算法求图像阈值, 对图像进行二值化
            #_, skin1 = cv2.threshold(cr1, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) 
            _, skin1 = cv2.threshold(cr1, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
            cv2.imshow("image", img)
    #        cv2.imshow("image CR", cr1)
            cv2.imshow("Skin Cr+OSTU", skin1 )
        elif k == 27:#检测到esc则退出  #ord('q'): #若检测到按键 ‘q’,退出
            break
    cap.release()
    cv2.destroyAllWindows()

    2.HSV颜色空间阈值分割

    # -*- coding: utf-8 -*-
    """
    Created on Mon Dec 10 15:30:18 2018
    
    @author: 1
    """
    
    import cv2
    import numpy as np
    from matplotlib import pyplot as plt
    ################################################################################
     
    print('Pixel Values Access')
     
    imgFile = 'test.jpg'
     
    # load an original image
    img = cv2.imread(imgFile)
    img1 = cv2.imread(imgFile)
    ################################################################################
     
    print('HSV Skin Model')
     
    rows,cols,channels = img.shape
     
    # convert color space from bgr to rgb                        
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
     
    # prepare an empty image space
    imgSkin = np.zeros(img.shape, np.uint8)
    # copy original image
    imgSkin = img.copy()                       
     
    # convert color space from rgb to hsv
    imgHsv = cv2.cvtColor(img, cv2.COLOR_RGB2HSV)
     
    for r in range(rows):
        for c in range(cols):
     
            # get values of hue, saturation and value
            # standard -- h range: [0,360]; s range: [0,1]; v range: [0,255]
            # opencv -- h range: [0,180]; s range: [0,255]; v range: [0,255]       
            H = imgHsv.item(r,c,0)
            S = imgHsv.item(r,c,1)
            V = imgHsv.item(r,c,2)
            
            # non-skin area if skin equals 0, skin area otherwise        
            skin = 0
                    
            if ((H >= 0) and (H <= 25 / 2)) or ((H >= 335 / 2) and (H <= 360 / 2)):
                if ((S >= 0.2 * 255) and (S <= 0.6 * 255)) and (V >= 0.4 * 255):
                    skin = 1
                    # print 'Skin detected!'
            
            if 0 == skin:
                imgSkin.itemset((r,c,0),0)
                imgSkin.itemset((r,c,1),0)                
                imgSkin.itemset((r,c,2),0)
     
    # display original image and skin image
    #img= imgSkin[...,::-1]
    #cv2.imwrite("HSV.jpg",img)
    #plt.subplot(1,2,1), plt.imshow(img), plt.title('Original Image'), plt.xticks([]), plt.yticks([])
    #plt.subplot(1,2,2), 
    img2= img1[...,::-1]
    plt.imshow(img2)
    plt.title('Original')
    plt.xticks([])
    plt.yticks([])
    #plt.imshow(imgSkin)
    #plt.title('HSV')
    plt.show()  
    
    
                                                  
    ################################################################################
    #img = cv2.imread('YCbCr OR.jpg', cv2.IMREAD_COLOR) 
    #hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) # 把图像转换到HSV色域
    #(_h, _s, _v) = cv2.split(hsv) # 图像分割, 分别获取h, s, v 通道分量图像
    #skin3 = np.zeros(_h.shape, dtype=np.uint8)  # 根据源图像的大小创建一个全0的矩阵,用于保存图像数据
    #(x, y) = _h.shape # 获取源图像数据的长和宽
    ## 遍历图像, 判断HSV通道的数值, 如果在指定范围中, 则置把新图像的点设为255,否则设为0
    #for i in  range(0, x):
    #    for j in  range(0, y):
    #        if (_h[i][j] >  7) and (_h[i][j] <  20) and (_s[i][j] >  28) and (_s[i][j] <  255) and (_v[i][j] >  50) and (_v[i][j] <  255):
    #            skin3[i][j] =  255
    #        else:
    #            skin3[i][j] =  0
    #cv2.imshow('YCbCr OR.jpg', img)
    #cv2.imshow('YCbCr OR.jpg' +  " Skin3 HSV", skin3)

    3.RGB阈值分割

    # -*- coding: utf-8 -*-
    """
    Created on Mon Dec 10 15:32:32 2018
    
    @author: 1
    """
    
    import cv2
    import numpy as np
    from matplotlib import pyplot as plt
    ################################################################################
     
    #print 'Pixel Values Access'
     
    imgFile = 'test.jpg'
     
    # load an original image
    img = cv2.imread(imgFile)
     
    # access a pixel at (row,column) coordinates
    px = img[150,200]
    #print 'Pixel Value at (150,200):',px
     
    # access a pixel from blue channel
    blue = img[150,200,0]
    # access a pixel from green channel
    green = img[150,200,1]
    # access a pixel from red channel
    red = img[150,200,2]
    #print 'Pixel Value from B,G,R channels at (150,200): ',blue,green,red
    ################################################################################
     
    #print 'Pixel Values Modification'
    # 
    img[150,200] = [0,0,0]
    #print 'Modified Pixel Value at (150,200):',px
    ################################################################################
    # better way: using numpy
     
    # access a pixel from blue channel
    blue = img.item(100,200,0)
    # access a pixel from green channel
    green = img.item(100,200,1)
    # access a pixel from red channel
    red = img.item(100,200,2)
    #print 'Pixel Value using Numpy from B,G,R channels at (100,200): ',blue,green,red
     
    # warning: we can only change pixels in gray or single-channel image
     
    # modify green value: (row,col,channel)
    img.itemset((100,200,1),255)
    # read green value
    green = img.item(100,200,1)
    #print 'Modified Green Channel Value Using Numpy at (100,200):',green
    ################################################################################
     
    #print 'Skin Model'
     
    rows,cols,channels = img.shape
     
    # prepare an empty image space
    imgSkin = np.zeros(img.shape, np.uint8)
    # copy original image
    imgSkin = img.copy()
     
    for r in range(rows):
        for c in range(cols):
     
            # get pixel value       
            B = img.item(r,c,0)
            G = img.item(r,c,1)
            R = img.item(r,c,2)
            
            # non-skin area if skin equals 0, skin area otherwise        
            skin = 0
                    
            if (abs(R - G) > 15) and (R > G) and (R > B):
                if (R > 95) and (G > 40) and (B > 20) and (max(R,G,B) - min(R,G,B) > 15):               
                    skin = 1    
                    # print 'Condition 1 satisfied!'
                elif (R > 220) and (G > 210) and (B > 170):
                    skin = 1
                    # print 'Condition 2 satisfied!'
            
            if 0 == skin:
                imgSkin.itemset((r,c,0),0)
                imgSkin.itemset((r,c,1),0)                
                imgSkin.itemset((r,c,2),0)
                # print 'Skin detected!'
     
    # convert color space of images because of the display difference between cv2 and matplotlib                         
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    #cv2.imwrite("RGB.jpg",imgSkin)
    imgSkin = cv2.cvtColor(imgSkin, cv2.COLOR_BGR2RGB)
     
    
    # display original image and skin image
    #plt.subplot(1,2,1), plt.imshow(img), plt.title('Original Image'), plt.xticks([]), plt.yticks([])
    #plt.subplot(1,2,2), 
    plt.imshow(imgSkin), plt.title('RGB'), plt.xticks([]), plt.yticks([])
    plt.show()                                                
    ################################################################################
     
    #print 'Waiting for Key Operation'
     
    k = cv2.waitKey(0)
     
    # wait for ESC key to exit
    if 27 == k:
        cv2.destroyAllWindows()

    4.YCbCr颜色空间方法一

    # -*- coding: utf-8 -*-
    """
    Created on Wed Dec  5 14:37:04 2018
    
    @author: 1
    """
    
    
    import cv2
    import numpy as np
    from matplotlib import pyplot as plt
    ################################################################################
     
    print ('Pixel Values Access')
     
    imgFile = 'test.jpg'
     
    # load an original image
    img = cv2.imread(imgFile)
    ################################################################################
     
    print ('YCbCr Skin Model')
     
    rows,cols,channels = img.shape
    ################################################################################
    # light compensation
     
    gamma = 0.95
     
    for r in range(rows):
        for c in range(cols):
            
            # get values of blue, green, red     
            B = img.item(r,c,0)
            G = img.item(r,c,1)
            R = img.item(r,c,2)
            
            # gamma correction
            B = int(B ** gamma)  
            G = int(G ** gamma) 
            R = int(R ** gamma)
            
            # set values of blue, green, red
            img.itemset((r,c,0), B)
            img.itemset((r,c,1), G)
            img.itemset((r,c,2), R)
                      
    ################################################################################
     
    # convert color space from rgb to ycbcr
    imgYcc = cv2.cvtColor(img, cv2.COLOR_BGR2YCR_CB)
     
    # convert color space from bgr to rgb                        
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
     
    # prepare an empty image space
    imgSkin = np.zeros(img.shape, np.uint8)
    # copy original image
    imgSkin = img.copy()                       
    ################################################################################
     
    # define variables for skin rules
     
    Wcb = 46.97
    Wcr = 38.76
     
    WHCb = 14
    WHCr = 10
    WLCb = 23
    WLCr = 20
     
    Ymin = 16
    Ymax = 235
     
    Kl = 125
    Kh = 188
     
    WCb = 0
    WCr = 0
     
    CbCenter = 0
    CrCenter = 0
    ################################################################################
     
    for r in range(rows):
        for c in range(cols):
            
            # non-skin area if skin equals 0, skin area otherwise        
            skin = 0
            
            ########################################################################
            
            # color space transformation
            
            # get values from ycbcr color space     
            Y = imgYcc.item(r,c,0)
            Cr = imgYcc.item(r,c,1)
            Cb = imgYcc.item(r,c,2)                                
                                                                                                            
            if Y < Kl:
                WCr = WLCr + (Y - Ymin) * (Wcr - WLCr) / (Kl - Ymin)
                WCb = WLCb + (Y - Ymin) * (Wcb - WLCb) / (Kl - Ymin)
                
                CrCenter = 154 - (Kl - Y) * (154 - 144) / (Kl - Ymin)
                CbCenter = 108 + (Kl - Y) * (118 - 108) / (Kl - Ymin)            
                
            elif Y > Kh:
                WCr = WHCr + (Y - Ymax) * (Wcr - WHCr) / (Ymax - Kh)
                WCb = WHCb + (Y - Ymax) * (Wcb - WHCb) / (Ymax - Kh)
     
                CrCenter = 154 + (Y - Kh) * (154 - 132) / (Ymax - Kh)
                CbCenter = 108 + (Y - Kh) * (118 - 108) / (Ymax - Kh) 
            
            if Y < Kl or Y > Kh:
                Cr = (Cr - CrCenter) * Wcr / WCr + 154            
                Cb = (Cb - CbCenter) * Wcb / WCb + 108
            ########################################################################
            
            # skin color detection
            
            if Cb > 77 and Cb < 127 and Cr > 133 and Cr < 173:
                skin = 1
                # print 'Skin detected!'
            
            if 0 == skin:
                imgSkin.itemset((r,c,0),0)
                imgSkin.itemset((r,c,1),0)                
                imgSkin.itemset((r,c,2),0)
     
    # display original image and skin image
    #plt.imshow(img)
    YCbCr_= imgSkin[...,::-1]#将Plt RGB转换到cv BGR
    #cv2.imwrite("YCbCr_4.jpg",YCbCr_)
    plt.imshow(imgSkin)
    plt.title('YCbCr')
    plt.axis('off')
    #plt.subplot(1,2,1), plt.imshow(img), plt.title('Original Image'), plt.xticks([]), plt.yticks([])
    #plt.subplot(1,2,2), plt.imshow(imgSkin), plt.title('Transformed YCbCr Skin Image'), plt.xticks([]), plt.yticks([])
    plt.show()                                                

    5.YCbCr颜色空间方法二

    # -*- coding: utf-8 -*-
    """
    Created on Mon Dec 10 15:37:03 2018
    
    @author: 1
    """
    import cv2
    import numpy as np
    
    img = cv2.imread('YCbCr OR.jpg', cv2.IMREAD_COLOR)
    ycrcb = cv2.cvtColor(img, cv2.COLOR_BGR2YCrCb) # 把图像转换到YUV色域
    (y, cr, cb) = cv2.split(ycrcb) # 图像分割, 分别获取y, cr, br通道分量图像
    skin2 = np.zeros(cr.shape, dtype=np.uint8) # 根据源图像的大小创建一个全0的矩阵,用于保存图像数据
    (x, y) = cr.shape # 获取源图像数据的长和宽
    # 遍历图像, 判断Cr和Br通道的数值, 如果在指定范围中, 则置把新图像的点设为255,否则设为0
    for i in  range(0, x): 
        for j in  range(0, y):
            if (cr[i][j] >  140) and (cr[i][j] <  175) and (cb[i][j] >  100) and (cb[i][j] <  120):
                skin2[i][j] =  255
            else:
                skin2[i][j] =  0
    cv2.imshow('YCbCr OR.jpg', img)
    cv2.imshow('YCbCr OR.jpg' +  " Skin2 Cr+Cb", skin2)
  • 相关阅读:
    java正则表达式四种常用的处理方式(匹配、分割、替代、获取)
    常用汉字 3500字
    常用汉字3500字,繁简体
    Java SimpleDateFormat用法
    idea 破解
    WEBPACKCONFIG 自动跳转 webstorm
    MyBatisCodeHelperPro插件破解版[2.9.7]
    数据湖与数仓技术优势对比
    安装 Docker最简单的快速的方式
    centos 8解决:Errors during downloading metadata for repository 'AppStream'
  • 原文地址:https://www.cnblogs.com/Manuel/p/10430172.html
Copyright © 2020-2023  润新知