opencv python搞个写轮眼

25 篇文章 1 订阅

最近又看了一遍忍界大战,试着做一个自动添加写轮眼的玩意儿。

思路:人脸检测——人眼检测——瞳孔分割——写轮眼添加——融合

opencv用的cascade进行人眼和人脸识别

import numpy as np
import cv2
import os

# multiple cascades: https://github.com/Itseez/opencv/tree/master/data/haarcascades
face_cascade = cv2.CascadeClassifier('.\\data\\haarcascades\\haarcascade_frontalface_default.xml')
eye_cascade = cv2.CascadeClassifier('.\\data\\haarcascades\\haarcascade_eye_tree_eyeglasses.xml')

index = 0

for root,dir_,files in os.walk("face_data"):
    for file_ in files:
        print(os.path.join(root,file_))
        img = cv2.imread(os.path.join(root,file_))
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        faces = face_cascade.detectMultiScale(gray, 1.3, 5)
        for (x,y,w,h) in faces:
            #人脸区域框
            cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
            roi_gray = gray[y:y+h, x:x+w]
            roi_color = img[y:y+h, x:x+w]
        
            #在检测到的人脸区域内检测眼睛
            eyes = eye_cascade.detectMultiScale(roi_gray)
            for (ex,ey,ew,eh) in eyes:
                if ew*eh<(w*h)//50:
                    continue
                #眼睛区域框
                eye_color = roi_color.copy()
                cv2.rectangle(roi_color,(ex-10,ey-10),(ex+ew+10,ey+eh+10),(0,255,0),2)        
                font = cv2.FONT_HERSHEY_SIMPLEX
                cv2.putText(img,'Eye',(ex+x,ey+y), font, 0.5, (11,255,255), 1, cv2.LINE_AA)
                # cv2.imshow('eye', eye_color[ey-10:ey+eh+10,ex-10:ex+ew+10])
                # cv2.waitKey()
                cv2.imwrite("eye_data/"+str(index)+".jpg",eye_color[ey-10:ey+eh+10,ex-10:ex+ew+10])
                index = index+1


        cv2.namedWindow('img', 1)
        cv2.imshow('img',img)
        cv2.waitKey()

瞳孔分割用了U^2net进行了训练,数据标了几十个

https://github.com/NathanUA/U-2-Net

最后就是写轮眼添加,写轮眼加到瞳孔分割的部分

import cv2
import numpy as np
import os

def drawInCircle(img_open, img, cont, cX, cY):
    # 绘制最大内接圆 # 最大内接圆——检索轮廓的方式
    c = cont    # 单个轮廓
    contours = cv2.findContours(img_open.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    src = img_open.copy()
    raw_dist = np.empty(src.shape, dtype=np.float32)
    for ii in range(src.shape[0]):
        for jj in range(src.shape[1]):
            raw_dist[ii, jj] = cv2.pointPolygonTest(c, (jj, ii), True)   # 检测点坐标,与c轮廓坐标的距离
    minVal, maxVal, _, maxDistPt = cv2.minMaxLoc(raw_dist)   # minMaxLoc查找最小和最大元素值及其位置ma
    maxVal = abs(maxVal)
    cv2.circle(img, (cX, cY), np.int(maxVal)-1, (255, 255, 255), 1, cv2.LINE_8, 0)    # 最大内接圆
    height = np.int(maxVal)-1
    return np.int(maxVal)-1

#def set_eye():\
xly = cv2.imread("xly.png",cv2.IMREAD_UNCHANGED)
b_channel, g_channel, r_channel, alph = cv2.split(xly)

for root,dir_,files in os.walk('eye_data'):
    for index,file_ in enumerate(files):
        file_mask = os.path.join("eye_mask",file_)
        pic_mask = cv2.imread(file_mask)
        pic_eye = cv2.imread(os.path.join(root,file_))
        gray = cv2.cvtColor(pic_mask,cv2.COLOR_BGR2GRAY)
        _,th_img = cv2.threshold(gray,100,255,cv2.THRESH_BINARY)
        contours, hier = cv2.findContours(th_img,
                                         cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

        center,radius = cv2.minEnclosingCircle(contours[0])
        r = int(radius)
        cX,cY = (int(center[0]),int(center[1]))
        pic_mask = cv2.circle(pic_mask,(cX,cY),r,(255,255,0),2)

        xly = cv2.resize(xly,(2*r,2*r))
        xly_roi = pic_eye[cY-r:cY+r,cX-r:cX+r]
        th_img_roi = th_img[cY-r:cY+r,cX-r:cX+r]
        for x in range(xly_roi.shape[0]):   # 图片的高
            for y in range(xly_roi.shape[1]):   # 图片的宽
                px = xly[x,y]
                if px[3]>0 and th_img_roi[x,y]>0:
                    px1 = px[:-1]
                    tx = 0.5*xly_roi[x,y]+0.5*px1
                    xly_roi[x,y] = tx
        cv2.imshow('pic_mask',pic_eye)
        cv2.waitKey()

最终效果:

搞定!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值