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

文章目录

  • 相关链接
  • 前言
  • 阈值
    • 阈值使用
      • 代码
        • 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 npimage = {"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); //窗口显示的标准图像的SizeMat 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); //窗口显示的标准图像的SizeMat 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.mzph.cn/news/655383.shtml

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

相关文章

C 变量

目录 1. C变量 2. C变量定义 2.1 变量初始化 2.2 C中的变量声明 3. C中的左值&#xff08;Lvalues&#xff09;和右值&#xff08;Rvalues&#xff09; 1. C变量 在C语言中&#xff0c;变量可以根据其类型分为以下几种基本类型&#xff1a; 整型变量&#xff1a;用…

自然语言nlp学习 三

4-8 Prompt-Learning--应用_哔哩哔哩_bilibili Prompt Learning&#xff08;提示学习&#xff09;是近年来在自然语言处理领域中&#xff0c;特别是在预训练-微调范式下的一个热门研究方向。它主要与大规模预训练模型如GPT系列、BERT等的应用密切相关。 在传统的微调过程中&a…

将vite项目(vue/react)使用vite-plugin-pwa配置为pwa应用,只需要3分钟即可

将项目配置为pwa模式&#xff0c;就可以在浏览器里面看到安装应用的选项&#xff0c;并且可以将web网页像app一样添加到手机桌面或者pad桌面上&#xff0c;或者是电脑桌面上&#xff0c;这样带来的体验就像真的在一个app上运行一样。为了实现这个目的&#xff0c;我们可以为vue…

算法设计与分析实验:滑动窗口与二分查找

目录 一、寻找两个正序数组的中位数 1.1 具体思路 1.2 流程展示 1.3 代码实现 1.4 代码复杂度分析 1.5 运行结果 二、X的平方根 2.1 具体思路 2.2 流程展示 2.3 代码实现 2.4 代码复杂度分析 2.5 运行结果 三、两数之和 II-输入有序数组 3.1 采用二分查找的思想 …

LeetCode —— 43. 字符串相乘

&#x1f636;‍&#x1f32b;️&#x1f636;‍&#x1f32b;️&#x1f636;‍&#x1f32b;️&#x1f636;‍&#x1f32b;️Take your time ! &#x1f636;‍&#x1f32b;️&#x1f636;‍&#x1f32b;️&#x1f636;‍&#x1f32b;️&#x1f636;‍&#x1f32b;️…

Bio-Rad(Abd serotec)独特性抗体

当一种抗体与另一种抗体的独特型结合时&#xff0c;它被称为抗独特型抗体。抗体的可变部分包括独特的抗原结合位点&#xff0c;称为独特型。独特型(即独特型)内表位的组合对于每种抗体都是独特的。 如今开发的大多数治疗性单克隆抗体是人的或人源化的&#xff0c;用于诱导抗药…

【国产MCU】-认识CH32V307及开发环境搭建

认识CH32V307及开发环境搭建 文章目录 认识CH32V307及开发环境搭建1、CH32V307介绍2、开发环境搭建3、程序固件下载1、CH32V307介绍 CH32V307是沁恒推出的一款基于32位RISC-V设计的互联型微控制器,配备了硬件堆栈区、快速中断入口,在标准RISC-V基础上大大提高了中断响应速度…

java 社区资源管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 java Web社区资源管系统是一套完善的java web信息管理系统 &#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysql5.…

bxCAN-中断

bxCAN中断 bxCAN 共有四个专用的中断向量。每个中断源均可通过 CAN 中断使能寄存器 (CAN_IER) 来单独地使能或禁止。 发送中断可由以下事件产生&#xff1a; 发送邮箱 0 变为空&#xff0c;CAN_TSR 寄存器的 RQCP0 位置 1。 发送邮箱 1 变为空&#xff0c;CAN_TSR 寄存器…

SkyWalking+es部署与使用

第一步下载skywalking :http://skywalking.apache.org/downloads/ 第二步下载es:https://www.elastic.co/cn/downloads/elasticsearch 注&#xff1a;skywalking 和es要版本对应&#xff0c;可从下面连接查看版本对应关系&#xff0c;8.5.0为skywalking 版本号 Index of /di…

Apache Commons Collection3.2.1反序列化分析(CC1)

Commons Collections简介 Commons Collections是Apache软件基金会的一个开源项目&#xff0c;它提供了一组可复用的数据结构和算法的实现&#xff0c;旨在扩展和增强Java集合框架&#xff0c;以便更好地满足不同类型应用的需求。该项目包含了多种不同类型的集合类、迭代器、队…

大数据学习之Redis、从零基础到入门(三)

目录 三、redis10大数据类型 1.哪十个&#xff1f; 1.1 redis字符串&#xff08;String&#xff09; 1.2 redis列表&#xff08;List&#xff09; 1.3 redis哈希表&#xff08;Hash&#xff09; 1.4 redis集合&#xff08;Set&#xff09; 1.5 redis有序集合&#xff08…

Android SystemUI 介绍

目录 一、什么是SystemUI 二、SystemUI应用源码 三、学习 SystemUI 的核心组件 四、修改状态与导航栏测试 本篇文章&#xff0c;主要科普的是Android SystemUI &#xff0c; 下一篇文章我们将介绍如何把Android SystemUI 应用转成Android Studio 工程项目。 一、什么是Syst…

华为配置小型网络WLAN 的基本业务示例

配置小型网络WLAN基本业务示例 组网图形 图1 配置小型网络WLAN基本业务组网图 小型WLAN网络简介配置注意事项组网需求数据规划配置思路操作步骤配置文件 小型WLAN网络简介 本文介绍的WLAN网络是指利用频率为2.4GHz或5GHz的射频信号作为传输介质的无线局域网&#xff0c;相对于有…

Vue之初识Vue CLI 脚手架

Vue CLI 是Vue 官方提供的一个全局命令工具 可以帮助我们快速创建一个开发Vue项目的标准化基础架子。【集成了webpack配置】 脚手架有什么好处&#xff1f; 1.开箱即用&#xff0c;零配置 2.内置 babel 等工具 3.标准化 使用步骤: 1.全局安装(一次):yarn globaladd vue/cli …

Hack The Box-Pov

信息收集&端口利用 先使用nmap对主机进行端口扫描 nmap 10.10.11.251只开放了80端口 访问网站后发现没有什么功能点,尝试目录扫描 并没有什么能够利用的点 使用gobuster进行子域名扫描 gobuster dns -d pov.htb -w /usr/share/wordlists/seclists/Discovery/DNS/subdo…

MSE Nacos 配置变更审计平台使用指南

作者&#xff1a;孙立&#xff08;涌月&#xff09;、邢学超&#xff08;于怀&#xff09;、李艳林&#xff08;彦林&#xff09; 配置审计平台简介 Nacos [ 1] 作为一款业界主流的微服务注册中心和配置中心&#xff0c;管理着企业核心的配置资产&#xff0c;由于配置变更的安…

聚醚醚酮(Polyether Ether Ketone)PEEK在粘接使用时使用UV胶水的优势有哪些?要注意哪些事项?

使用UV胶水在聚醚醚酮&#xff08;Polyether Ether Ketone&#xff0c;PEEK&#xff09;上进行粘接可能具有一些优势&#xff0c;但同时也需要注意一些事项。以下是使用UV胶水的优势和需要考虑的事项&#xff1a; 优势&#xff1a; 1.快速固化&#xff1a; UV胶水通常具有快速…

spark window源码探索

核心类&#xff1a; 1. WindowExec 物理执行逻辑入口&#xff0c;主要doExecute()和父类WindowExecBase 2. WindowFunctionFrame 窗框执行抽象&#xff0c;其子类对应sql语句的不同窗框 其中又抽象出BoundOrdering类, 用于判断一行是否在界限内(Bound), 分为RowBoundOrdering…

总结10(break和continue)

break break如果用于循环是用来终止循环 break如果用于switch&#xff0c;则是用于终止switch break不能直接用于if&#xff0c;除非if属于循环内部的一个子句&#xff08;下图为举例&#xff09; 例1&#xff1a; &#xff08;该图中break与if没有关系&#xff0c;只终止for循…