C++PythonC# 三语言OpenCV从零开发(7):图像的阈值

news2024/11/17 8:49:00

文章目录

  • 相关链接
  • 前言
  • 阈值
    • 阈值使用
      • 代码
        • Python
        • C++
        • Csharp
          • csharp代码问题
  • 总结

相关链接

C++&Python&Csharp in OpenCV 专栏

【2022B站最好的OpenCV课程推荐】OpenCV从入门到实战 全套课程(附带课程课件资料+课件笔记)

OpenCV一个窗口同时显示多张图片 (C++)

前言

我感觉我之前的比较实在是太过于偏代码了,缺少了图形学的知识的记录。之后的笔记我会把图形学的知识也记录上去。

阈值

阈值简单来说就是增强图片的对比。用过Ps的人就知道阈值是什么意思,在电脑绘画中用的还是比较多的

在这里插入图片描述

阈值使用

在这里插入图片描述

代码

Python
# %%
# 导入包
import cv2
import matplotlib.pyplot as plt
import numpy as np

image = {
    "image":'',
    "gray":'',
    
}

image["image"] = cv2.imread("D:/workSpace/OpenCV/HellOpenCV/Resources/image/cat.png")

# 获取颜色通道,因为cv2是BGR的顺序,所以这里是B 灰度
image["gray"]= cv2.split(image['image'])[0]

thresh = {
    '1' : '','2': '','3': '','4': '','5': ''
}

# 调用不同的阈值处理算子
ret , thresh['1'] = cv2.threshold(image['gray'],127,255,cv2.THRESH_BINARY)
ret , thresh['2'] = cv2.threshold(image['gray'],127,255,cv2.THRESH_BINARY_INV)
ret , thresh['3'] = cv2.threshold(image['gray'],127,255,cv2.THRESH_TRUNC)
ret , thresh['4'] = cv2.threshold(image['gray'],127,255,cv2.THRESH_TOZERO)
ret , thresh['5'] = cv2.threshold(image['gray'],127,255,cv2.THRESH_TOZERO_INV)

# 将数据总和成数组
titles = ['iamge','binary','binary inv','trunc','tozero','tozero inv']
images = [image['gray'],thresh['1'],thresh['2'],thresh['3'],thresh['4'],thresh['5']]

# 循环赋值到plt中
for i in range(6):
    plt.subplot(2,3,i+1),plt.imshow(images[i],'gray')
    plt.title(titles[i])
    plt.xticks([]),plt.yticks([])

plt.show()

在这里插入图片描述

C++

这里为了一次性展示多个窗口,我就CSDN上面找了个方法

OpenCV一个窗口同时显示多张图片 (C++)


#include <opencv2/opencv.hpp>  
#include <opencv2/core/core.hpp>  
#include <opencv2/highgui/highgui.hpp>  
#include <opencv2/imgproc.hpp>  
#include<iostream>  
#include <vector>
using namespace std;
using namespace cv;


vector<Mat> imageVector;

void multipleImage(vector<Mat> imgVector, Mat& dst, int imgCols)
{
	const int MAX_PIXEL = 300;
	int imgNum = imgVector.size();
	//选择图片最大的一边 将最大的边按比例变为300像素
	Size imgOriSize = imgVector[0].size();
	int imgMaxPixel = max(imgOriSize.height, imgOriSize.width);
	//获取最大像素变为MAX_PIXEL的比例因子
	double prop = imgMaxPixel < MAX_PIXEL ? (double)imgMaxPixel / MAX_PIXEL : MAX_PIXEL / (double)imgMaxPixel;
	Size imgStdSize(imgOriSize.width * prop, imgOriSize.height * prop); //窗口显示的标准图像的Size

	Mat imgStd; //标准图片
	Point2i location(0, 0); //坐标点(从0,0开始)
	//构建窗口大小 通道与imageVector[0]的通道一样
	Mat imgWindow(imgStdSize.height * ((imgNum - 1) / imgCols + 1), imgStdSize.width * imgCols, imgVector[0].type());
	for (int i = 0; i < imgNum; i++)
	{
		location.x = (i % imgCols) * imgStdSize.width;
		location.y = (i / imgCols) * imgStdSize.height;
		resize(imgVector[i], imgStd, imgStdSize, prop, prop, INTER_LINEAR); //设置为标准大小
		imgStd.copyTo(imgWindow(Rect(location, imgStdSize)));
	}
	dst = imgWindow;
}

int main()
{
	auto image = imread("D:/workSpace/OpenCV/HellOpenCV/Resources/image/cat.png");
	Mat showImage;

	Mat bgr[3];
	split(image, bgr);
	Mat gray = bgr[0];

	Mat thresh[5];

	threshold(gray, thresh[0], 127, 255, THRESH_BINARY);
	threshold(gray, thresh[1], 127, 255, THRESH_BINARY_INV);
	threshold(gray, thresh[2], 127, 255, THRESH_TRUNC);
	threshold(gray, thresh[3], 127, 255, THRESH_TOZERO);
	threshold(gray, thresh[4], 127, 255, THRESH_TOZERO_INV);


	vector<Mat> images{gray,thresh[0],thresh[1], thresh[2], thresh[3], thresh[4], };

	multipleImage(images, showImage, 3);

	imshow("C++", showImage);

	waitKey(0);
	destroyAllWindows();
	return 0;
}

在这里插入图片描述

Csharp

还是那句话,C++跑通了,Csharp抄抄就可以了。
在这里插入图片描述

using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace HelloOpenCV.Utils
{
    public static class MyOpenCV_Extensions
    {

        /// <summary>
        /// 3通道遍历
        /// </summary>
        /// <param name="mat"></param>
        /// <returns></returns>
        public static int[,,] MatToArray(Mat mat)
        {

            var res = new int[mat.Rows, mat.Cols, mat.Channels()];
            for (var i = 0; i < mat.Rows; i++)
            {

                for (var j = 0; j < mat.Cols; j++)
                {
                    var temp = mat.At<Vec3b>(i, j);
                    res[i, j, 0] = temp[0];
                    res[i, j, 1] = temp[1];
                    res[i, j, 2] = temp[2];
                }
            }
            return res;
        }

        public static Mat MultipleImage(List<Mat> lists, int imgCols)
        {
            const int MAX_PIXEL = 300;
            int imgNum = lists.Count;
            //选择图片最大的一边 将最大的边按比例变为300像素
            Size imgOriSize = lists[0].Size();
            int imgMaxPixel = Math.Max(imgOriSize.Height, imgOriSize.Width);
            //获取最大像素变为MAX_PIXEL的比例因子
            double prop = imgMaxPixel < MAX_PIXEL ? (double)imgMaxPixel / MAX_PIXEL : MAX_PIXEL / (double)imgMaxPixel;
            Size imgStdSize= new Size(imgOriSize.Width* prop, imgOriSize.Height* prop); //窗口显示的标准图像的Size

            Mat imgStd = new Mat(); //标准图片
            
            Point location = new Point(0, 0); //坐标点(从0,0开始)
                                    //构建窗口大小 通道与imageVector[0]的通道一样
            Mat imgWindow = new Mat(imgStdSize.Height* ((imgNum -1) / imgCols + 1), imgStdSize.Width* imgCols, lists[0].Type());
            for (int i = 0; i < imgNum; i++)
            {
                location.X = (i % imgCols) * imgStdSize.Width;
                location.Y = (i / imgCols) * imgStdSize.Height;
                Cv2.Resize(lists[i], imgStd, imgStdSize, prop, prop, InterpolationFlags.Linear); //设置为标准大小
                imgStd.CopyTo(new Mat(imgWindow, new Rect(location, imgStdSize)) ); 
            }
            return imgWindow;
        }
    }
}

运行代码

 static void Main(string[] args)
 {
     Mat image = Cv2.ImRead("D:/workSpace/OpenCV/HellOpenCV/Resources/image/cat.png");

     Mat[] bgr = new Mat[3];
     Cv2.Split(image, out bgr);
     Mat gray = bgr[0];

     Mat[] threshs = new Mat[5];
     for(var i = 0; i < threshs.Length; i++)
     {
         threshs[i] = new Mat();
     }
     Cv2.Threshold(gray, threshs[0], 127, 255, ThresholdTypes.Binary);
     Cv2.Threshold(gray, threshs[1], 127, 255, ThresholdTypes.BinaryInv);
     Cv2.Threshold(gray, threshs[2], 127, 255, ThresholdTypes.Trunc);
     Cv2.Threshold(gray, threshs[3], 127, 255, ThresholdTypes.Tozero);
     Cv2.Threshold(gray, threshs[4], 127, 255, ThresholdTypes.TozeroInv);

     var res = MyOpenCV_Extensions.MultipleImage(new List<Mat>() {
         gray, threshs[0], threshs[1], threshs[2], threshs[3], threshs[4] 
     }, 3);


     Cv2.ImShow("Csharp", res);

     Cv2.WaitKey(0);
     Cv2.DestroyAllWindows();


 }

在这里插入图片描述

csharp代码问题

遇到了几个坑

C++是能直接把变量当做构造函数的,C# 对应的代码是构造函数里面带Mat参数的

在这里插入图片描述
在这里插入图片描述
而且C++的构造函数还不好定位,我进去找不到源码。我不知道C++ 的代码是怎么调试的,毕竟没怎么接触过

在这里插入图片描述

总结

跟之前的套路差不多,Python跑通,C++ 翻译Python+上网查资料,Csharp翻译C++。我还是觉得Csharp优雅多了,写起来舒服,C++ 这个语法用起来有点痛苦。而且C++ 报错天天给我报内存变量报错,我哪里能看得懂啊,顶多定位到哪行代码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1419804.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++提取ICO图标(PE文件资源提取)

最近需要写一个提取EXE或者DLL图标资源的功能, 网上找了很久, 要么功能不好用, 最后结果如下: 1.很多是加载为HICON句柄后转换为图片保存, 全损画质..., 2.后来找了个还能用的, 详见 https://github.com/TortoiseGit/TortoiseGit/blob/master/src/Utils/IconExtractor.cpp …

【Axure教程0基础入门】04交互动效基础

04交互动效基础 1.Axure交互事件的基本概念 &#xff08;1&#xff09;交互动效Interaction 原型图中&#xff0c;原件与页面的动态效果&#xff08;dynamic behaviors&#xff09;。 &#xff08;2&#xff09;交互动效的构成 目标&#xff08;target&#xff09;&#xff1a;…

Windows系统本地安装Wnmp服务并结合内网穿透公网远程访问

目录 前言 1.Wnmp下载安装 2.Wnmp设置 3.安装cpolar内网穿透 3.1 注册账号 3.2 下载cpolar客户端 3.3 登录cpolar web ui管理界面 3.4 创建公网地址 4.固定公网地址访问 结语 作者简介&#xff1a; 懒大王敲代码&#xff0c;计算机专业应届生 今天给大家聊聊Windows…

我用Rust开发Rocketmq name server

我是蚂蚁背大象(Apache EventMesh PMC&Committer)&#xff0c;文章对你有帮助给Rocketmq-rust star,关注我GitHub:mxsm&#xff0c;文章有不正确的地方请您斧正,创建ISSUE提交PR~谢谢! Emal:mxsmapache.com 1. Rocketmq-rust namesrv概述 经过一个多月的开发&#xff0c;终…

【Docker】docker安装jenkins

一、执行命令 下载jenkins镜像 #下载jenkins 镜像 docker pull jenkins/jenkins:latest-jdk8 启动jenkins容器 #启动jenkins 容器 #挂载 如果不挂载 每次启动jenkins的配置、插件、用户等信息都没有了 #jenkins_home 包含jenkins配置、插件、用户等信息。 要指定必须配置用…

StarRocks-3.1.0 单节点部署

1. 相关环境准备 FE&#xff1a; /opt/starrocks BE&#xff1a; /opt/starrocks 安装包下载 wget https://releases.starrocks.io/starrocks/StarRocks-3.1.0.tar.gz解压缩 tar -zxvf StarRocks-3.1.0.tar.gz 安装jdk (v2.5 及以上版本建议安装 JDK 11&#xff0c;我们使用…

260:vue+openlayers 通过webgl方式加载矢量图层

第260个 点击查看专栏目录 本示例介绍如何在vue+openlayers中通过webgl方式加载矢量图层。在做这个示例的时候,采用vite的方式而非webpack的方式。这里的基础设置需要改变一下。 ol的版本7.5.2或者更高。 直接复制下面的 vue+openlayers源代码,操作2分钟即可运行实现效果 文…

探索数字经济:从基础到前沿的奇妙旅程

新一轮技术革命方兴未艾&#xff0c;特别是以人工智能、大数据、物联网等为代表的数字技术革命&#xff0c;催生了一系列新技术、新产业、新模式&#xff0c;深刻改变着世界经济面貌。数字经济已成为重组全球要素资源、重塑全球经济结构、改变全球竞争格局的关键力量。预估到20…

ICLR 2024 Oral|微软推出多模态数学测试基准MathVista,挑战Google Gemini

微软等机构提出了首个以视觉场景为核心的数学推理基准 — MathVista。他们提供了一份长达 116 页的详尽报告&#xff0c;其中深入剖析了包括 GPT-4V 在内的 12 个大型模型的性能。令人瞩目的是&#xff0c;MathVista 已被 Google Gemini 采纳为其多模态数学测试的标准之一。此项…

Docker 安装与基本操作

目录 一、Docker 概述 1、Docker 简述 2、Docker 的优势 3、Docker与虚拟机的区别 4、Docker 的核心概念 1&#xff09;镜像 2&#xff09;容器 3&#xff09;仓库 二、Docker 安装 1、命令&#xff1a; 2、实操&#xff1a; 三、Docker 镜像操作 1、命令&#xff1…

Unity中使用Ultraleap的InteractionButton组件

本节在上一节基础上进行&#xff0c;上一小结参考如下&#xff1a; Unity中创建Ultraleap 3Di交互项目 本节工程文件如下&#xff1a; Unity中使用Ultraleap的InteractionButton组件 本节结构有所更改&#xff0c;主要是参考官方示例结构进行重新调整&#xff0c;和上一小节相…

torch与cuda\cudnn和torchvision的对应

以上图片来源于这篇博客 于是&#xff0c;我需要手动下载0.9.0torchvision 直接在网站https://pypi.tuna.tsinghua.edu.cn/simple/后面加上torchvision&#xff0c;就不用ctrlF搜torchvision了&#xff0c;即进入下面这个网站&#xff0c;找到对应版本的包下载安装即可 https…

蓝桥杯2024/1/26笔记-----基于PCF8591的电压采集装置

功能实现要求&#xff1a; 每次建好工程文件夹&#xff0c;里边包含User&#xff08;放工程文件&#xff0c;mian.c&#xff0c;可以在这里写如同我这个文章的文本文档&#xff09;、Driver&#xff08;存放底层文件如Led.c&#xff0c;Led.h等&#xff09; 新建的工程先搭建框…

LeetCode.209. 长度最小的子数组

题目 题目链接 分析 本题的题意就是让我们找最短的子数组和 > target 的子数组的长度。 首先最能想到的就是暴力方法&#xff0c;外层循环以数组每一个元素都作为起点&#xff0c;内存循环累加元素&#xff0c;当大于等于 target 的时候记录当前元素个数&#xff0c;更新…

Security ❀ HTTP/HTTPS逐包解析交互过程细节

文章目录 1. TCP三次握手机制2. HTTP Request 请求报文3. HTTP Response 响应报文4. SSL/TLS协议4.1. ClientHello 客户端Hello报文4.2 ServerHello 服务器Hello报文4.3. *ServerKeyExchange 服务公钥交换4.4. ClientKeyExchange 客户端公钥交换4.5. *CertificateVerify 证书验…

机器学习-pandas(含数据)

pandas 优势&#xff1a; 增强图表可读性便捷的数据处理能力读取文件方便封装了Matplotlib、Numpy的画图和计算 更详细的教程&#xff1a;Pandas 教程 | 菜鸟教程 (runoob.com) Pandas数据结构 Pandas中一共有三种数据结构&#xff0c;分别为&#xff1a;Series、DataFram…

Python 二维码开源库之segno使用详解

概要 Python Segno 是一个用于生成二维码的开源库&#xff0c;它提供了丰富的功能和灵活的选项&#xff0c;可以帮助开发者轻松地生成各种类型的二维码。本文将介绍如何使用 Python Segno 创建二维码&#xff0c;并深入探讨其功能和用法。 什么是 Python Segno&#xff1f; P…

SV-8003V 网络寻呼话筒

SV-8003V是深圳锐科达电子有限公司的一款桌面式对讲主机SV-8003V同样作为广播对讲系统的核心组成部分&#xff0c;集成有全区广播、分区广播、单点呼叫、点对点对讲、以及监听等功能。SV-8003V使用铝合金拉丝面板&#xff0c;并配有高性能的鹅颈麦克风以及高保真的全频喇叭&…

测试ASP.NET Core项目调用EasyCaching的基本用法(Redis)

EasyCaching中的包EasyCaching.Redis和EasyCaching.CSRedis都支持集成Redis实现缓存&#xff0c;前者基于StackExchange.Redis&#xff0c;而后者基于CSRedisCore&#xff0c;本文学习使用EasyCaching.Redis包连接redis服务实现缓存的基本用法。   新建WebApi项目&#xff0c…

Springboot自定义线程池实现多线程任务

1. 在启动类添加EnableAsync注解 2.自定义线程池 package com.bt.springboot.config;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.concurrent.ThreadPoolTask…