图像处理:图片二值化学习,以及代码中如何实现

news/2024/7/21 3:51:08 标签: 图像处理, 计算机视觉, 人工智能

目录

1、了解下图片二值化的含义

2、进行图像二值化处理的方法

3、如何选择合适的阈值进行二值化

4、实现图片二值化(代码)

(1)是使用C++和OpenCV库实现:

(2)纯C++代码实现,不要借助其他库


1、了解下图片二值化的含义

(1)图片二值化是一种图像处理技术,它将彩色或灰度图像转换为只包含两个颜色的图像,通常是黑色和白色。这种转换是通过将图像中的每个像素的灰度值与一个阈值进行比较来实现的。

(2)在二值化过程中,如果像素的灰度值大于或等于阈值,则将该像素设置为白色(或亮色),否则将其设置为黑色(或暗色)。这样,图像中的每个像素都被映射到黑色或白色之一,从而产生了一个只有两种颜色的二值图像。

(3)二值化可以用于很多应用,例如文字识别、图像分割、形状检测等。通过将图像转换为二值图像,可以突出显示目标物体的轮廓和特征,并简化后续的图像处理任务。

2、进行图像二值化处理的方法

进行图像二值化处理的方法有多种,下面介绍两种常用的方法:

(1)全局阈值法(Global Thresholding):

        该方法假设整个图像的前景和背景具有明显的灰度差异,并且通过选择一个全局阈值来将图像分为两个部分。

具体步骤如下:

        1)将彩色或灰度图像转换为灰度图像。

        2)选择一个合适的全局阈值。

        3)遍历图像中的每个像素,如果像素的灰度值大于等于阈值,则将其设置为白色;否则将其设置为黑色。

(2)自适应阈值法(Adaptive Thresholding):

        该方法考虑到图像不同区域的光照条件可能不同,因此使用局部阈值来对图像进行分割。

具体步骤如下:

        1)将彩色或灰度图像转换为灰度图像。

        2)将图像分成多个小的局部区域。

        3)对每个局部区域计算一个适应性阈值。

        4)遍历图像中的每个像素,根据所在的局部区域的阈值将像素设置为黑色或白色。

这些方法可以使用图像处理库或软件实现,例如OpenCV、Python的PIL库等。具体的实现方式和参数选择会根据具体的图像和需求而有所不同。

3、如何选择合适的阈值进行二值化

选择合适的阈值进行图像二值化是一个关键的步骤,下面介绍几种常用的阈值选择方法:

(1)固定阈值法(Fixed Thresholding):该方法是最简单a(2)Otsu's 阈值法:Otsu's 阈值法是一种自动选择阈值的方法,它能够找到一个最佳的阈值,使得分割后的图像类间方差最大化。这种方法适用于具有双峰直方图的图像,其中前景和背景的灰度值分布明显不同。

(3)自适应阈值法(Adaptive Thresholding):自适应阈值法根据图像局部区域的灰度特性来选择阈值。它将图像分成多个小的局部区域,并对每个区域计算一个适应性阈值。这种方法适用于光照条件不均匀的图像。

(4)大津法与自适应阈值法的结合:有时候可以结合使用大津法和自适应阈值法,先使用大津法确定一个全局阈值,然后再使用自适应阈值法对图像进行细分割。

选择合适的阈值方法取决于图像的特性和需求。一般来说,如果图像具有明显的前景和背景差异,固定阈值法可能是一个简单有效的选择。如果图像的灰度分布复杂或光照条件不均匀,可以考虑使用自适应阈值法或Otsu's 阈值法。

4、实现图片二值化(代码)

(1)是使用C++和OpenCV库实现:

#include <opencv2/opencv.hpp>

int main() 
{
    // 读取图像
    cv::Mat image = cv::imread("input.jpg", cv::IMREAD_GRAYSCALE);

    // 检查图像是否成功读取
    if (image.empty()) {
        std::cout << "无法读取图像文件" << std::endl;
        return -1;
    }

    // 应用全局阈值法进行二值化
    cv::Mat binaryImage;
    double thresholdValue = 128; // 阈值设为128

    double maxValue = 255; // 最大值设为255

    cv::threshold(image, binaryImage, thresholdValue, maxValue, cv::THRESH_BINARY);

    // 显示原始图像和二值化后的图像
    cv::imshow("Original Image", image);
    cv::imshow("Binary Image", binaryImage);
    cv::waitKey(0);

    return 0;
}
(2)纯C++代码实现,不要借助其他库

#include <iostream>
#include <fstream>

struct RGB {
    unsigned char r, g, b;
};

int main() 
{
    // 读取图像
    std::ifstream file("input.bmp", std::ios::binary);

    if (!file) 
    {
        std::cout << "无法打开图像文件" << std::endl;
        return -1;
    }

    // 读取图像头信息
    char header[54];
    file.read(header, sizeof(header));

    int width = *(int*)&header[18];
    int height = *(int*)&header[22];
    int imageSize = width * height;

    // 分配内存并读取图像数据
    RGB* imageData = new RGB[imageSize];
    file.read((char*)imageData, imageSize * sizeof(RGB));
    file.close();

    // 将彩色图像转换为灰度图像
    unsigned char* grayImage = new unsigned char[imageSize];

    for (int i = 0; i < imageSize; i++) 
    {
        grayImage[i] = (imageData[i].r + imageData[i].g + imageData[i].b) / 3;
    }

    // 应用阈值进行二值化
    unsigned char thresholdValue = 128;

    for (int i = 0; i < imageSize; i++) 
    {
        if (grayImage[i] >= thresholdValue) 
            grayImage[i] = 255; // 白色
        else 
            grayImage[i] = 0; // 黑色
    }

    // 保存二值化后的图像
    std::ofstream outputFile("output.bmp", std::ios::binary);

    if (!outputFile) 
    {
        std::cout << "无法保存图像文件" << std::endl;
        return -1;
    }

    // 写入图像头信息
    outputFile.write(header, sizeof(header));

    // 写入二值化后的图像数据
    outputFile.write((char*)grayImage, imageSize);
    outputFile.close();

    delete[] imageData;
    delete[] grayImage;

    return 0;
}

在上述代码中,我们使用C++的文件输入输出流来读取和保存图像文件。首先,我们读取图像的头信息,并根据宽度和高度计算图像数据的大小。然后,我们分配内存并读取彩色图像数据。接下来,我们将彩色图像转换为灰度图像,通过对每个像素的RGB值求平均来计算灰度值。最后,我们应用阈值进行二值化处理,将灰度值大于等于阈值的像素设置为白色(255),小于阈值的像素设置为黑色(0)。最后,我们保存二值化后的图像。

请注意,上述代码假设输入图像为24位位图(BMP)格式,并且图像文件名为"input.bmp"。你可以根据实际情况修改文件名和图像格式。此外,该代码只适用于处理较小的图像,如果要处理更大的图像,可能需要优化内存使用和读写操作。


http://www.niftyadmin.cn/n/5138162.html

相关文章

UG\NX二次开发 获取图层所在的图层类别

文章作者:里海 来源网站:《里海NX二次开发3000例专栏》 感谢粉丝订阅 感谢 大熊猫小竹子 订阅本专栏,非常感谢。 简介 获取图层所在的图层类别,比如获取20层所在的图层类别。已经封装好函数。 效果 代码 #include "me.hpp"using namespace std;//获取图层所在的…

QMS质量检验管理|攻克制造企业质量检验难题,助力企业提质增效

在日益激烈的市场竞争中&#xff0c;对产品质量严格把关&#xff0c;是制造企业提高核心竞争力与品牌价值的关键因素。那如何高效、高质地完成产品质检工作&#xff1f;这就需要企业在工业质检中引进数字化技术加以辅助&#xff0c;进而推动智能制造高质量发展。 蓝库云QMS质量…

TSINGSEE青犀AI视频识别技术+危化安全生产智慧监管方案

一、背景分析 石油与化学工业生产过程复杂多样&#xff0c;涉及的物料易燃易爆、有毒有害&#xff0c;生产条件多高温高压、低温负压&#xff0c;现场危险化学品存储量大、危险源集中&#xff0c;重特大安全事故多发。打造基于工业互联网的安全生产新型能力&#xff0c;提高危…

木马免杀(篇三)静态免杀方法

紧接上一篇&#xff0c;是通过 cs 生成 shellcode 并直接用python 调用动态链接库执行 shellcode 。 生成后的exe文件未进行任何处理。 现在学习一些可以绕过静态免杀的方法。即将文件上传到目标不会被杀软查杀&#xff0c;但这只是静态方面。 动态免杀方面还涉及到很多东西&…

java Arrays.sort 自定义排序

package com.data.entity;import java.util.Comparator;public class StudentComparator implements Comparator<Student> {Overridepublic int compare(Student o1, Student o2) {/** - 从小到大:- o1的值>o2的值,return正数- o1的值<o2的值, return负数- 相等ret…

国家数据局成立,公共数据如何掘金?

国家数据局揭牌&#xff1a;引领新时代数据要素管理和开发的重大举措 筹建7个多月后&#xff0c;10月25日&#xff0c;国家数据局正式揭牌。根据《党和国家机构改革方案》&#xff0c;国家数据局负责协调推进数据基础制度建设&#xff0c;统筹数据资源整合共享和开发利用&…

5000张照片怎么快速发给别人?分享三个简单的方法!

有的时候我们不得不一次性发送很多图片&#xff0c;一张一张发实在让人头疼&#xff0c;这个时候就需要借助一些图片压缩工具打包成文件压缩包发送。下面介绍了三种好用的方法&#xff0c;一起来看看吧&#xff5e; 方法一&#xff1a;使用微信助手 可以使用微信助手&#xff…

Java入门篇 之 逻辑控制

博主的文章希望对大家有所帮助 今日份励志文案:凌空虚度&#xff0c;难成千秋伟业&#xff1b;求真务实&#xff0c;方能善作善成 冲冲冲&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 目录 一.if~else语句 1.1.if-else语句基本用法&#xff1a; 1.2.代码…