3 opencv平滑边缘锯齿代码

本文介绍了一种使用OpenCV实现轮廓平滑的方法,通过高斯模糊处理轮廓上的点,以达到平滑的效果。此外,还提供了另一种中值滤波的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 找出轮廓然后在处理

#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main(int argc, const char** argv)
{
    //Mat im = imread("D:\\software\\opencv2413\\opencv\\sources\\samples\\cpp\\baboon.jpg", 0);
    Mat im = imread("pred_5.png", 0);
    Mat cont = ~im;
    Mat original = Mat::zeros(im.rows, im.cols, CV_8UC3);
    Mat smoothed = Mat(im.rows, im.cols, CV_8UC3, Scalar(255, 255, 255));

    // contour smoothing parameters for gaussian filter
    int filterRadius = 5;
    int filterSize = 2 * filterRadius + 1;
    double sigma = 10;

    vector<vector<Point> > contours;
    vector<Vec4i> hierarchy;
    // find contours and store all contour points
    findContours(cont, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE, Point(0, 0));
    for (size_t j = 0; j < contours.size(); j++)
    {
        // extract x and y coordinates of points. we'll consider these as 1-D signals
        // add circular padding to 1-D signals
        size_t len = contours[j].size() + 2 * filterRadius;
        size_t idx = (contours[j].size() - filterRadius);
        vector<float> x, y;
        for (size_t i = 0; i < len; i++)
        {
            x.push_back(contours[j][(idx + i) % contours[j].size()].x);
            y.push_back(contours[j][(idx + i) % contours[j].size()].y);
        }
        // filter 1-D signals
        vector<float> xFilt, yFilt;
        GaussianBlur(x, xFilt, Size(filterSize, filterSize), sigma, sigma);
        GaussianBlur(y, yFilt, Size(filterSize, filterSize), sigma, sigma);
        // build smoothed contour
        vector<vector<Point> > smoothContours;
        vector<Point> smooth;
        for (size_t i = filterRadius; i < contours[j].size() + filterRadius; i++)
        {
            smooth.push_back(Point(xFilt[i], yFilt[i]));
        }
        smoothContours.push_back(smooth);

        Scalar color;

        if (hierarchy[j][3] < 0)
        {
            color = Scalar(0, 0, 0);
        }
        else
        {
            color = Scalar(255, 255, 255);
        }
        drawContours(smoothed, smoothContours, 0, color, -1);
    }
    imshow("result", smoothed);
    waitKey(0);
}

问题来源:
http://stackoverflow.com/questions/37409811/smoothing-edges-of-a-binary-image

我发现中值滤波效果也很好:

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('pred_5.png')
median = cv2.medianBlur(img,5)
cv2.imwrite('median.png',median)
### Python OpenCV 实现图像边缘锯齿 为了实现图像边缘的抗锯齿效果,可以采用多种方法来改善图像质量。一种常见的方式是对PNG图片中的Alpha通道进行特殊处理[^3]。 #### Alpha通道优化 当读取带有透明度信息(PNG格式)的文件时,如果忽略了alpha通道,则可能导致半透明像素被错误地渲染成完全透明,从而造成视觉上的锯齿现象。因此,在加载这类图像之前应该确保正确获取其四个颜色分量(即RGBA),而不是默认只提取RGB三原色: ```python import cv2 import numpy as np # 加载带Alpha通道的PNG图像 image_with_alpha = cv2.imread(&#39;path_to_your_image.png&#39;, cv2.IMREAD_UNCHANGED) if image_with_alpha.shape[2] == 4: # 如果存在Alpha层 alpha_channel = image_with_alpha[:, :, 3] # 创建掩码用于后续操作 _, mask = cv2.threshold(alpha_channel, 0, 255, cv2.THRESH_BINARY) else: print("该图像不包含Alpha通道") ``` #### 使用模糊技术减少伪影 对于已经存在的锯齿问题,可以通过应用适当的滤镜来进行修正。虽然这可能会使某些细节变得稍微模糊一些,但是能够显著提高整体观感。这里推荐两种常用的算法——中值滤波器和高斯滤波器: ##### 中值滤波器 这种方法特别适合去除椒盐噪声的同时保留边界清晰度: ```python median_blurred_img = cv2.medianBlur(image_with_alpha, ksize=3) ``` ##### 高斯滤波器 此方式通过加权平均相邻像素值达到柔化目的,参数sigmaX控制权重分布范围;通常情况下设置为零让函数自动计算最佳值即可获得不错的效果: ```python gaussian_blurred_img = cv2.GaussianBlur(image_with_alpha,(5,5), sigmaX=0) ``` 需要注意的是,上述两种方法都适用于整个图像区域,而不仅仅是针对边缘部分。实际应用场景下可能还需要结合其他手段进一步增强特定部位的表现力。 #### 结合形态学运算提升轮廓表现 除了简单的平滑外,还可以利用形态学膨胀/腐蚀等基本变换突出物体外形特征并消除细碎干扰结构。例如下面的例子展示了如何使用闭运算(先膨胀再腐蚀)强化目标物周边线条流畅性: ```python kernel = np.ones((3,3),np.uint8) closed_contours = cv2.morphologyEx(median_blurred_img,cv2.MORPH_CLOSE,kernel ) ``` 综上所述,通过对PNG图像的Alpha通道敏感处理以及合理运用各种类型的滤波技术和形态学算子,可以在很大程度上缓解甚至解决由不当采样引起的阶梯状失真问题,进而达成理想的抗锯齿效果。
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值