zoukankan      html  css  js  c++  java
  • 肤色阈值分割

    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)
  • 相关阅读:
    我的WCF之旅(1):创建一个简单的WCF程序
    与众不同 windows phone (15) Media(媒体)之后台播放音频
    与众不同 windows phone (14) Media(媒体)之音频播放器, 视频播放器, 与 Windows Phone 的音乐和视频中心集成
    与众不同 windows phone (10) Push Notification(推送通知)之推送 Tile 通知, 推送自定义信息
    与众不同 windows phone (17) Graphic and Animation(画图和动画)
    与众不同 windows phone (5) Chooser(选择器)
    与众不同 windows phone (26) Contacts and Calendar(联系人和日历)
    与众不同 windows phone (7) Local Database(本地数据库)
    与众不同 windows phone (19) Device(设备)之陀螺仪传感器, Motion API
    与众不同 windows phone (16) Media(媒体)之编辑图片, 保存图片到相册, 与图片的上下文菜单“应用程序...”和“共享...”关联, 与 Windows Phone 的图片中心集成
  • 原文地址:https://www.cnblogs.com/Manuel/p/10430172.html
Copyright © 2011-2022 走看看