首页 > 编程语言 >C#+OpenCV基础(十)_灰度变化与直方图

C#+OpenCV基础(十)_灰度变化与直方图

时间:2024-07-10 17:10:47浏览次数:16  
标签:Mat C# hists int 直方图 灰度 new 256

1、灰度图的线性变换

/// <summary>
/// 灰度图的线性变换
/// OpenCVHelper.GRAY_LinearTransform(srcMat, 1.2, 40)
/// </summary>
/// <param name="grayMat">灰度图片</param>
/// <param name="a">乘数</param>
/// <param name="b">常数</param>
/// <returns></returns>
public static Mat GRAY_LinearTransform(Mat grayMat, double a, int b)
{
    Mat dstMat = new Mat();
    grayMat.CopyTo(dstMat);

    for (int w = 0; w < grayMat.Width; w++)
    {
        for (int h = 0; h < grayMat.Height; h++)
        {
            byte color = grayMat.At<byte>(h, w);
            int colorNew = Convert.ToInt32(a * color + b);
            colorNew = colorNew > 255 ? 255 : colorNew;

            dstMat.At<byte>(h, w) = Convert.ToByte(colorNew);
        }
    }

    return dstMat;
}

2、灰度图的分段线性变换

/// <summary>
/// 灰度图的分段线性变换
/// OpenCVHelper.GRAY_DividedLinearTransform(srcMat, 70, 200, 100, 200)
/// </summary>
/// <param name="grayMat">灰度图片</param>
/// <param name="fStart">分段区间起点</param>
/// <param name="fEnd">分段区间终点</param>
/// <param name="fSOut">映射区间起点</param>
/// <param name="fEOut">映射区间终点</param>
/// <returns></returns>
public static Mat GRAY_DividedLinearTransform(Mat grayMat, float fStart, float fEnd, float fSOut, float fEOut)
{
    Mat dstMat = Mat.Zeros(grayMat.Size(), grayMat.Type());

    // 计算直线参数
    // L1
    float fK1 = fSOut / fStart;
    // L2
    float fK2 = (fEOut - fSOut) / (fEnd - fStart);
    float fC2 = fSOut - fK2 * fStart;
    // L3
    float fK3 = (255.0f - fEOut) / (255.0f - fEnd);
    float fC3 = 255.0f - fK3 * 255.0f;

    // 建立查询表
    byte[] loolUpTable = new byte[256];
    for (int m = 0; m < 256; m++)
    {
        if (m < fStart)
        {
            loolUpTable[m] = Convert.ToByte(m * fK1);
        }
        else if (m > fEnd)
        {
            loolUpTable[m] = Convert.ToByte(m * fK3 + fC3);
        }
        else
        {
            loolUpTable[m] = Convert.ToByte(m * fK2 + fC2);
        }
    }

    // 灰度映射
    for (int w = 0; w < grayMat.Width; w++)
    {
        for (int h = 0; h < grayMat.Height; h++)
        {
            int index = grayMat.At<byte>(h, w);
            dstMat.At<byte>(h, w) = loolUpTable[index];
        }
    }

    return dstMat;
}

3、直方图 - 多通道合并

/// <summary>
/// 计算图片的直方图 - 多通道合并
/// OpenCVHelper.CalcHist(srcMat, [0, 1, 2], null,1, [256], [new Rangef(0, 256)])
/// </summary>
/// <param name="mat">图片</param>
/// <param name="channels">需要统计的通道索引;灰度图就是[0],BGR就是[0][1][2]; new int[3] { 0, 1, 2 }</param>
/// <param name="mask">操作掩码;用于统计出统计直方图的数据元素个数</param>
/// <param name="dims">需要收集的数据数量;直方图一般只需要收集灰度级一种,所以一般为1</param>
/// <param name="histSize">存放每个直方图尺寸的数组,一般为256; new int[] { 256 }</param>
/// <param name="ranges">像素值范围常为[0 256]; new Rangef[] { new Rangef(0, 256) }</param>
/// <param name="uniform">指示直方图是否均匀;默认为true</param>
/// <param name="accumulate">累计标识符;默认为false</param>
/// <returns>输出的图片直方图</returns>
public static Mat CalcHist(Mat mat, int[] channels, InputArray? mask, int dims,
    int[] histSize, Rangef[] ranges, bool uniform = true, bool accumulate = false)
{
    Mat[] mats = Cv2.Split(mat);

    Mat hist = new Mat();
    Cv2.CalcHist(mats, channels, mask, hist, dims, histSize, ranges, uniform, accumulate);
    Cv2.Normalize(hist, hist, 0, 256, NormTypes.MinMax);  // 归一化

    // 画直方图
    Cv2.MinMaxLoc(hist, out double minVal, out double maxVal);
    int height = 512;
    int width = 512;

    hist = hist * (maxVal != 0 ? height / maxVal : 0.0);

    Mat histImage = new Mat(512, 512, MatType.CV_8UC3, new Scalar(100, 100, 100));  // 直方图画布
    int binW = (int)((double)width / histSize[0]);

    for (int i = 0; i < histSize[0]; i++)
    {
        histImage.Rectangle(
            new Point(i * binW, histImage.Rows - (int)hist.Get<float>(i)),
            new Point((i + 1) * binW, histImage.Rows),
            new Scalar(255, 255, 255),
            -1);
    }

    return histImage;
}

4、直方图 - BGR三通道拆分

/// <summary>
/// 计算BGR图片的三色直方图 - BGR三通道拆分
/// OpenCVHelper.CalcHist_BGR(srcMat, null)
/// </summary>
/// <param name="mat">图片</param>
/// <param name="mask">操作掩码;用于统计出统计直方图的数据元素个数</param>
/// <param name="uniform">指示直方图是否均匀;默认为true</param>
/// <param name="accumulate">累计标识符;默认为false</param>
/// <returns>输出的图片直方图</returns>
public static Mat CalcHist_BGR(Mat mat, InputArray? mask, bool uniform = true, bool accumulate = false)
{
    Mat[] mats = Cv2.Split(mat);
    Mat[] mats0 = [mats[0]];  // B
    Mat[] mats1 = [mats[1]];  // G
    Mat[] mats2 = [mats[2]];  // R

    Mat[] hists = [new Mat(), new Mat(), new Mat()];

    int histSize = 256;
    Cv2.CalcHist(mats0, [0], mask, hists[0], 1, [histSize], [new Rangef(0, 256)], uniform, accumulate);
    Cv2.CalcHist(mats1, [0], mask, hists[1], 1, [histSize], [new Rangef(0, 256)], uniform, accumulate);
    Cv2.CalcHist(mats2, [0], mask, hists[2], 1, [histSize], [new Rangef(0, 256)], uniform, accumulate);
    Cv2.Normalize(hists[0], hists[0], 0, 256, NormTypes.MinMax);  // 归一化
    Cv2.Normalize(hists[1], hists[1], 0, 256, NormTypes.MinMax);  // 归一化
    Cv2.Normalize(hists[2], hists[2], 0, 256, NormTypes.MinMax);  // 归一化

    // 画直方图
    Cv2.MinMaxLoc(hists[0], out double minVal0, out double maxVal0);
    Cv2.MinMaxLoc(hists[1], out double minVal1, out double maxVal1);
    Cv2.MinMaxLoc(hists[2], out double minVal2, out double maxVal2);

    double minVal = Math.Min(minVal0, Math.Min(minVal1, minVal2));
    double maxVal = Math.Max(maxVal0, Math.Max(maxVal1, maxVal2));

    int height = 512;
    int width = 512;

    hists[0] = hists[0] * (maxVal != 0 ? height / maxVal : 0.0);
    hists[1] = hists[1] * (maxVal != 0 ? height / maxVal : 0.0);
    hists[2] = hists[2] * (maxVal != 0 ? height / maxVal : 0.0);

    Mat histImage = new Mat(512, 512, MatType.CV_8UC3, new Scalar(100, 100, 100));  // 直方图画布
    int binW = (int)((double)width / histSize);

    for (int i = 0; i < histSize; i++)
    {
        histImage.Rectangle(
            new Point(i * binW, histImage.Rows - (int)hists[0].Get<float>(i)),
            new Point((i + 1) * binW, histImage.Rows),
            new Scalar(255, 0, 0),
            -1);
        histImage.Rectangle(
            new Point(i * binW, histImage.Rows - (int)hists[1].Get<float>(i)),
            new Point((i + 1) * binW, histImage.Rows),
            new Scalar(0, 255, 0),
            -1);
        histImage.Rectangle(
            new Point(i * binW, histImage.Rows - (int)hists[2].Get<float>(i)),
            new Point((i + 1) * binW, histImage.Rows),
            new Scalar(0, 0, 255),
            -1);
    }

    return histImage;
}

5、直方图 - 均衡化

/// <summary>
/// 直方图均衡化
/// </summary>
/// <param name="grayMat">灰度图片</param>
/// <returns></returns>
public static Mat EqualizeHist(Mat grayMat)
{
    Mat dst = new Mat();
    Cv2.EqualizeHist(grayMat, dst);
    return dst;
}

标签:Mat,C#,hists,int,直方图,灰度,new,256
From: https://www.cnblogs.com/qq2806933146xiaobai/p/18294519

相关文章

  • [ABC361D]Go Stone Puzzle
    题目大意给定一个字符串S,它是由B和W组成,之后在S后面添加两个空格,可以将相邻的两个字符和空格进行交换,交换的前提是只能相邻,同时两个字符必须都是B或者W,再给一个字符串T,也是由B和W组成,问最小经过几次交换,使得S变成T\(1\leq|S|\leq14\)题解:看到数据范围,一看就知道是个搜索,怎......
  • SMU Summer 2024 Contest Round 3(7.10)
    寻找素数对思路:数的范围为10000,直接筛出所有范围内的质数,n2的枚举所有质数对和的情况#include<bits/stdc++.h>usingnamespacestd;#defineintlonglong#definePIIpair<int,int>constintN=1e4+5;vector<int>pri;intidx,st[N];voidinit(){for(in......
  • 【Mathematical Model】基于Python的相关性/显著性分析&成图
        很久之前编写的代码了,当时是用来分析遥感波段组合对于某地物反演的相关性分析。今天正好整理数据时一块分享出来。原创作者:RS迷途小书童博客地址:https://blog.csdn.net/m0_56729804?type=blog1相关性的概念        “相关性”是统计学中的一个基本......
  • C#+OpenCV基础(九)_拆分合并图层
    1、图片拆分通道图层///<summary>///图片拆分通道图层///</summary>///<paramname="mat">图片</param>///<returns></returns>publicstaticMat[]SplitChannel(Matmat){//拆分通道Cv2.Split(mat,outMat[]mats);ret......
  • 你真的懂多线程吗?多线程 并行处理 CPU 操作系统
    了解多线程、并行处理首先需要了解什么CPU、CPU核数、操作系统CPU物理数即电脑拥有的物理CPU数量,普通电脑一般只有一个CPU插槽,也就是只有一个物理CPU。我们日常说的CPU,就是指封装好的一个物理CPU,作为商品进行售卖。但在编程讨论时,某些情况下,我们说的CPU含义又是指其中一个运算......
  • 【打卡】006 P6 VGG-16算法-Pytorch实现人脸识别
    >-**......
  • 推送单据信息到第三方系统(NC65)
    此处以预付款申请单推动付款结算单到NC系统为例 目录一、Action二、Service三、ServiceImpl四、 FcVoucherUtil的 settlementXML方法(json转xml的方法)五、 FcVoucherUtil的doPost方法(推送NC的方法)一、ActionpublicActionFormgetZhiwu(ActionMapping......
  • echarts 如何设置 legend 展示为虚线或者实线
    文章目录一、操作步骤1.找虚线或者实线的svg2.echarts中legend部分的完整代码3.预览效果总结一、操作步骤1.找虚线或者实线的svg在阿里巴巴矢量图标库里面找相应的内容。截图:复制里面的svg代码如下(实线举例):<svgt="1720600860976"class="icon"viewBox="00......
  • 深入剖析C++的 “属性“(Attribute specifier sequence)
    引言在阅读开源项目源代码是,发现了一个有趣且特殊的C++特性:属性。属性(attributespecifiersequences)是在C++11标准引入的。在C++11之前,编译器特有的扩展被广泛用来提供额外的代码信息。例如,GNU编译器(GCC)使用__attribute__来控制函数的行为。但是缺点也很明显,那就是这种方......
  • 使用clickhous自带的Prometheus监控时,clickhous相关指标解释说明
    找了一圈没发现关于这些指标的说明,特地记录下:指标解释ClickHouseProfileEvents_Query已执行的查询总数,帮助监控数据库的查询负载,了解数据库的使用频率和工作负载。ClickHouseProfileEvents_SelectQuery已执行的SELECT查询总数,了解读操作的负载情况,评估查询优化效果......