当前位置: 首页 > article >正文

OpenCV笔记3-图像修复

图像修复

图像修复是计算机视觉中的一类算法,其目标是填充图像或视频内的区域。该区域使用二进制掩模进行标识,填充通常根据需要填充的区域边界信息来完成。图像修复的最常见应用是恢复旧的扫描照片。图像修复不仅可以去除图像中得“划痕”,它还用于删除图像中的小的不需要的对象(去除图像中得水印、日期等)。

OpenCV 实现了两种修复算法:

  1. “一种基于快速行进法的图像修复技术”,Alexandru Telea,2004: 这是基于快速行进法(FMM)。查看要修复的区域,该算法首先从边界像素开始,然后到达边界内的像素。它用背景中像素的加权和替换每个要修复的像素,将更多的权重赋予更近的像素和边界像素。
  2. “纳维尔-斯托克斯,流体动力学,图像和视频修复”,贝尔塔米奥,马塞洛,安德里亚·l·贝尔托齐和吉列尔莫·萨皮罗,2001: 该算法受偏微分方程的启发。从边缘(已知区域)开始向未知区域传播等照度线(连接同强度点的线)。最后,区域中的变化被最小化以填充颜色。

Image Inpainting with OpenCV (C++/Python) | LearnOpenCV # 

理论可以看看这篇。

dst = cv2.inpaint(src, inpaintMask, inpaintRadius, flags)来实现修复图像,

参数含义:

src:源图像,也就是需要修复的图像

inpaintMask:二进制掩码,指示要修复的像素。

dst:结果图像

inpaintRadius:表示修复的半径

flags : 修复算法

import cv2
import rclpy
from rclpy.node import Node
import numpy as np
from ament_index_python.packages import get_package_share_directory #获取shares目录绝对路径

class OpenCVNode(Node):
    def readImg(self,img_name: str):
        default_image_path = get_package_share_directory('yahboom_esp32ai_car')+'/resource/'
        self.get_logger().info(f'打开图片:{default_image_path}')
        dam_img = cv2.imread(default_image_path+img_name)

        #mask =  np.zeros((height,width,1),np.uint8)
        #灰度
        gray = cv2.cvtColor(dam_img,cv2.COLOR_BGR2GRAY)
        #2值化
        _,mask = cv2.threshold(gray,150,255,cv2.THRESH_BINARY_INV)
        #
        # kernel_3X3 = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))#构造卷积核 
        # mask_after_open = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel_3X3)#形态学  

        dst_fmm = cv2.inpaint(src=dam_img, inpaintMask=mask, inpaintRadius=3, flags=cv2.INPAINT_TELEA)
        dst_ns = cv2.inpaint(dam_img,mask,10,cv2.INPAINT_NS)
        cv2.imshow('dam_img',dam_img) 
        cv2.imshow('paint',mask)
        cv2.imshow('Inpaint Output using FMM', dst_fmm)
        cv2.imshow('Inpaint Output using ns',dst_ns)
   
        cv2.waitKey(0)

def main():
    rclpy.init()
    node = OpenCVNode('opencvNode')
    node.readImg('d3.jpg') 
    rclpy.spin(node)
    rclpy.shutdown()

我自己测试了下,关键是掩模的生成,算法效果区别不大。简单图像对比明显的效果好,背景复杂的干扰项效果较差。效果好的:

效果不好的修复

图片亮度增强

简单来说就是调整rgb的值。可以看看大佬们写的专业分析

8、OpenCV调整图像对比度和亮度_照片对比度csdn-CSDN博客

import cv2
import rclpy
from rclpy.node import Node
import numpy as np
import math
from ament_index_python.packages import get_package_share_directory #获取shares目录绝对路径

class OpenCVNode(Node):

    def readImg(self,img_name: str):
        default_image_path = get_package_share_directory('yahboom_esp32ai_car')+'/resource/'
        self.get_logger().info(f'打开图片:{default_image_path}')
        img = cv2.imread(default_image_path+img_name)
 
        gamma_val = 0.5
        #gamma
        gamma_table = [np.power(x / 255.0, gamma_val) * 255.0 for x in range(256)]  # 建立映射表
        gamma_table = np.round(np.array(gamma_table)).astype(np.uint8)  # 颜色值为整数
        img_gamma = cv2.LUT(img, gamma_table)  # 图片颜色查表。另外可以根据光强(颜色)均匀化原则设计自适应算法。
        #
        cv2.imshow('img',img) 
        cv2.imshow('img_gamma',img_gamma) 
   
        cv2.waitKey(0)


def main():
    rclpy.init()
    node = OpenCVNode('opencvNode')
    node.readImg('20.jpg') 
    rclpy.spin(node)
    rclpy.shutdown()

当然这里还有很多细节参数的,直接调整过大,图片处理不好容易过曝。

效果如下:

图片磨皮

磨皮算法的核心就是让皮肤区域的像素变得平滑,过渡自然,让皮肤看起来十分光滑。

我大概在网上搜了下,效果好一些的大佬主要包含了两部分:滤波算法、皮肤区域检测、肤色提取等。这个比较复杂,因为不加区域的话,过滤完图片很多细节会丢失,所以需要指定区域去美化效果才好。

这里就先测试下opencv的单个函数,没有深入学习。简单了解下:双边滤波(Bilateral filter) 是一种非线性的滤波方法,是结合图像的空间邻近度和像素值相似度的一种折中处理,同时考虑空域信息和灰度相似性,达到保边去噪的目的。具有简单、非迭代、局部的特点。双边滤波优点:对边缘信息有较好的保留,缺点:不能较好的消除噪声

推荐几个大佬写的,可以对比下大佬的效果:

https://zhuanlan.zhihu.com/p/407017507  这篇讲理论

[Opencv基础]人脸磨皮_cv 磨皮算法-CSDN博客

我的这个磨皮测试图片也是用的这个,明显还是大佬的专业,效果好,推荐大家看看。

void bilateralFilter( InputArray src, 
                      OutputArray dst, 
                      int d,
                      double sigmaColor, 
                      double sigmaSpace,
                      int borderType = BORDER_DEFAULT );

参数:

  • 第一个参数,InputArray类型的src,输入图像,即源图像,需要为8位或者浮点型单通道、三通道的图像。
  • 第二个参数,OutputArray类型的dst,即目标图像,需要和源图片有一样的尺寸和类型。
  • 第三个参数,int类型的d,表示在过滤过程中每个像素邻域的直径。如果这个值我们设其为非正数,那么OpenCV会从第五个参数sigmaSpace来计算出它来。
  • 第四个参数,double类型的sigmaColor,颜色空间滤波器的sigma
  • 。这个参数的值越大,就表明该像素邻域内有更宽广的颜色会被混合到一起,产生较大的半相等颜色区域。
  • 第五个参数,double类型的sigmaSpace坐标空间中滤波器的sigma值,坐标空间的标注方差。他的数值越大,意味着越远的像素会相互影响,从而使更大的区域足够相似的颜色获取相同的颜色。当d>0,d指定了邻域大小且与sigmaSpace无关。否则,d正比于sigmaSpace。
  • 第六个参数,int类型的borderType,用于推断图像外部像素的某种边界模式。注意它有默认值BORDER_DEFAULT。
import cv2
import rclpy
from rclpy.node import Node
import numpy as np
import math
from ament_index_python.packages import get_package_share_directory #获取shares目录绝对路径

class OpenCVNode(Node):

    def readImg(self,img_name: str):
        default_image_path = get_package_share_directory('yahboom_esp32ai_car')+'/resource/'
        self.get_logger().info(f'打开图片:{default_image_path}')
        img = cv2.imread(default_image_path+img_name)
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
       # 进行离散傅里叶变换
        #dft = cv2.dft(np.float32(gray), flags=cv2.DFT_COMPLEX_OUTPUT)
        kernel = np.ones((3,3),np.float32)
        kernel = kernel/9.
        # 使用高斯滤波器对频域图像进行滤波
        #blurred = cv2.GaussianBlur(img, (3, 3), 0)
        smoothed = cv2.bilateralFilter(img, 10, 30, 30)
     
        cv2.imshow('img',img) 
        cv2.imshow('smoothed',smoothed) 
   
        cv2.waitKey(0)


def main():
    rclpy.init()
    node = OpenCVNode('opencvNode')
    node.readImg('9.jpg') 
    rclpy.spin(node)
    rclpy.shutdown()

 效果如下:


http://www.kler.cn/a/512024.html

相关文章:

  • 基于VSCode+CMake+debootstrap搭建Ubuntu交叉编译开发环境
  • 鸿蒙子组件根据数据,刷新item Ui的规范
  • Python新春烟花
  • python3GUI--仿崩坏三二次元登录页面(附下载地址) By:PyQt5
  • 什么宠物最好养?
  • KubeSphere部署安装,接入KubeKey安装的k8s集群
  • [深度学习]机器学习和深度学习
  • ElasticSearch索引别名的应用
  • Ubuntu 24.04 LTS 系统语言英文改中文
  • CSS 圆形头像和破图时显示默认图片
  • 高水平EI会议-第四届机器学习、云计算与智能挖掘国际会议
  • leetcode 面试经典 150 题:合并区间
  • vue2使用flv.js在浏览器打开flv格式视频
  • 解锁辅助驾驶新境界:基于昇腾 AI 异构计算架构 CANN 的应用探秘
  • MongoDB的安装、配置和基本操作
  • 09、PT工具用法
  • PHP基础(下)
  • 数学基础 --线性代数之理解矩阵乘法
  • 如何解析返回的快递费用数据?
  • Android开发与网络请求
  • 【sass+css变量实现换肤】
  • Maven项目中没有.iml文件
  • 编辑器Vim基本模式和指令 --【Linux基础开发工具】
  • 深入解析MIMIC IV数据库中 labevents 和 chatevents 数据表的区别与联系
  • .Net Core微服务入门全纪录(五)——Ocelot-API网关(下)
  • 定制setsockopt只设置一次实现指定sock的永久quickack