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)