祛除红眼算法python实现

news/2024/10/18 2:37:21/

最近研究了一下祛除红眼的算法,主要的思想都是将RGB通道里面的R通道给想法设法的降低,其他的通道稍微进行变换就行,这里使用python运行了一下例子看看,

version2参考了代码:https://www.cnblogs.com/cpuimage/p/9000203.html

使用python进行了重新复现,这个算法的效果很不错,比起遍地都是的方法(version1)会好一些,version1方法会明显祛除不干净的,初步猜测是version1方法里面使用的简单粗暴的mask,这个mask应该不够准确和平滑,会导致后续的效果精度不足。


import math
import cv2
import numpy as npdef fillHoles(mask):maskFloodfill = mask.copy()h, w = maskFloodfill.shape[:2]maskTemp = np.zeros((h+2, w+2), np.uint8)    cv2.floodFill(maskFloodfill, maskTemp, (0, 0), 255)mask2 = cv2.bitwise_not(maskFloodfill)return mask2 | maskdef remove_red_eyes_version1(img):imgOut = img.copy()eyesCascade = cv2.CascadeClassifier("haarcascade_eye.xml")eyes = eyesCascade.detectMultiScale(img, scaleFactor=1.3)for (x, y, w, h) in eyes:eye = img[y:y+h, x:x+w]b = eye[:, :, 0]g = eye[:, :, 1]r = eye[:, :, 2]bg = cv2.add(b, g)mask = (r > 150) &  (r > bg)mask = mask.astype(np.uint8)mask = fillHoles(mask)mask = cv2.dilate(mask, None, anchor=(-1, -1), iterations=3)mean = bg / 2mask = mask.astype(np.bool)[:, :, np.newaxis]mean = mean[:, :, np.newaxis]eyeOut = eye.copy()eyeOut = np.where(mask, mean, eyeOut)imgOut[y:y+h, x:x+w, :] = eyeOutreturn imgOutdef remove_red_eyes_version2(img_input, radius):img_out = img_input.copy()height, width = img_input.shape[:2]eyesCascade = cv2.CascadeClassifier("haarcascade_eye.xml")eyes = eyesCascade.detectMultiScale(img_input, scaleFactor=1.3)img_input=img_input.astype(float)for (x, y, w, h) in eyes:center_x=x+w//2center_y=y+h//2'''#因为这个眼睛检测算法精度不是很好,很可能存在误检测的情况,这里只能先简单过滤一下,可以选择更好的眼睛检测算法'''if w*h<100*100:continueleft = np.clip(int(center_x - radius), 0, width)top = np.clip(int(center_y - radius), 0, height)right = np.clip(int(center_x + radius), 0, width)bottom = np.clip(int(center_y + radius), 0, height)pow_radius = radius * radiusfor y in range(top, bottom):offset_y = y - center_yfor x in range(left, right):offset_x = x - center_xdis = offset_x*offset_x+offset_y*offset_yif dis <= pow_radius:red = img_input[y, x, 2]green = img_input[y, x, 1]blue = img_input[y, x, 0]nrv = blue+greenif nrv < 1:nrv = 1if green > 1:bluf = blue/greenelse:bluf = bluebluf = max(0.5, min(1.5, math.sqrt(bluf)))#获取一个数值为0.5到1.5之间的数值redq = red/(nrv*bluf)if redq > 0.7:powr = 1.775-(redq*0.75+0.25)#可以看到如果redq越大,powr就越小,也就是说如果红色分量越大,powr就越小if powr < 0:powr = 0powr = powr*powrpowb = 0.5+0.5*powr#因为powr大于0,所以powb大于0.5powg = 0.75+0.25*powr#因为powr大于0,所以powg大于0.75img_out[y, x, 2] = powr*red+0.5img_out[y, x, 1] = powg*green+0.5img_out[y, x, 0] = powb*blue+0.5return img_outif __name__ == '__main__' :img = cv2.imread("34.jpg", cv2.IMREAD_COLOR)imgOut = remove_red_eyes_version1(img)imgOut2=remove_red_eyes_version2(img, 20)cv2.imwrite('imgOut.jpg',imgOut)cv2.imwrite('imgOut2.jpg',imgOut2)

效果图:

 我再放大一些可能会更加明显

我们可以清楚的看到,version2效果会平滑很多,没有明显的瑕疵。

-----------------------------------------------分割线----------------------------------------------

看了一下gimp也有去除红眼的算法,会更加简单,使用python也很容易实现,结果会更加好一些,而且阈值可以调整

def red_eye_removal(img, threshold=0.4):out_img = img.copy()assert 0.0 <= threshold <= 0.8eyesCascade = cv2.CascadeClassifier("haarcascade_eye.xml")eyes = eyesCascade.detectMultiScale(img, scaleFactor=1.3)for (x, y, w, h) in eyes:eye = img[y:y + h, x:x + w]eyeOut = eye.copy()adjusted_red = eye[:, :, 2]*0.5133333adjusted_green = eye[:, :, 1]*1.0adjusted_blue = eye[:, :, 0]*0.1933333adjusted_threshold = (threshold - 0.4) * 2flag1 = np.logical_and(adjusted_red >= adjusted_green - adjusted_threshold, True)flag2 = np.logical_and(adjusted_red >= adjusted_blue - adjusted_threshold, True)flag = np.logical_and(flag1, flag2)tmp = (adjusted_green + adjusted_blue) / (2.0 * 0.5133333)tmp = np.clip(tmp, 0.0, 1.0)eyeOut[:, :, 2] = np.where(flag, tmp, eye[:, :, 2])out_img[y:y + h, x:x + w, :] = eyeOutreturn out_img

 


http://www.ppmy.cn/news/784120.html

相关文章

PicoNEO3离线升级包5.2.3版本

如果你是担心升级到最新版后无法安装学习版资源&#xff0c;请先看该教程 Pico4&Pico3 5.3版本破解游戏版权认证的工具来啦&#xff01; https://www.bilibili.com/read/cv21711908 5.2.3旧版 MD5&#xff1a;C8012B4F3E8D77AAB4BB52663438855F 使用离线升级包时建议先…

S32DS 3.4 3.5颜色配色方案及代码自动补全提示

S32DS_3.4_3.5_插件 11.92 MB (3 files) org.eclipse.cdt.ui_6.6.100.202009302259.jar_替S32DS_3.4版 5.94 MBorg.eclipse.cdt.ui_7.2.0.202110051412.jar_替S32DS_3.5版 5.98 MBS32DS 3.4_3.5_eclipse_C_Cplusplus_Style颜色主题配置.epf 6.06 KB 使用方法&#xff1a; ①…

dlib实现红眼特效

效果 &#xff08;图片来源网络&#xff0c;如有侵权请联系删除&#xff09; 摘要 技术栈如下&#xff1a; 代码演示&#xff1a;python 面部关键点识别&#xff1a;dlib 图像处理&#xff1a;pillow&#xff0c;opencv 人脸关键点 既然是做人眼部位的贴图&#xff0c…

数字图像处理——红眼去除(Python)

输入的图像一般都是RGB三层&#xff0c;但是红眼区域的定义是在HSI空间上进行定义&#xff0c;因此需要存在两个函数将图像数据在RGB空间与HSI空间进行转换&#xff0c;而转换的公式如下图所示&#xff1a; 原始图片数据&#xff1a; 实验代码&#xff1a; import mathi…

k8s的资源配置清单的管理操作

目录 一、资源配置清单1.1 初步认识资源清单中svc的重要配置项1.2 手动编写 svc资源配置1.3 手动生成模板&#xff0c;再编写资源清单1.4 写yaml太累怎么办&#xff1f;1.5 官网下载资源模板 一、资源配置清单 Kubernetes 支持 YAML 和 JSON 格式管理资源对象 JSON 格式&#…

sqlserver数据库命令行客户端安装

项目情况 项目上需要通过执行sql语句去更新一些功能 直接进入数据库去进行执行太麻烦&#xff0c; 对基础技术人员的要求比较高&#xff0c;执行效率低 参考资料 sqlcmd 实用工具 - SQL Server | Microsoft Learn 下载 ODBC Driver for SQL Server - ODBC Driver for SQL S…

Windows 10 启动出现蓝屏 终止代码:UNMOUNTABLE_BOOT_VOLUME

解决办法&#xff1a;在命令符窗口中【管理员权限】 1、– 修复Windows文件&#xff1a;损坏的Windows文件可能会导致严重的问题。 sfc /scannow2 、– 修复硬盘&#xff1a;确保您的硬盘依次运行&#xff0c;以及Windows。 chkdsk c: /f 或 chkdsk /f 或 chkdsk /r

win10蓝屏:终止代码:CRITICAL_PROCESS_DIED

1.硬件驱动问题 Win X打开设备管理器-扫描检测硬件改动 看是否有硬件驱动问题&#xff08;黄色标识&#xff09;&#xff0c;有的话更新或卸载重装 2.查看蓝屏原因 使用软件&#xff1a; BlueScreenView WinX - 时间查看器 window日志-系统&#xff1a;红色错误标识为系统错误…