图像处理算法研究的程序框架

目录

1 程序框架简介

2 C#图像读取、显示、保存模块

3 C动态库图像算法模块

4 C#调用C动态库

5 演示Demo

5.1 开发环境

5.2 功能介绍

5.3 下载地址

参考


1 程序框架简介

        一个图像处理算法研究的常用程序逻辑框架,如下图所示

        在该框架中,将图像处理算法产品分为上层模块和底层模块两个部分。

        底层模块使用C/C++实现算法API,提供给上层模块调用;上层模块执行调用API和一些界面功能的实现,最后得到不同平台的软件产品。

        本文使用使用C/C++进行图像算法API开发,具有安全、高效和方便多平台移植的优点,目前大多数图像软件都是基于C/C++来开发的;使用C#来做上层调用与界面设计,是因为C#具有优秀的面向对象能力,界面设计方便快捷,而且对于图像读取、保存、显示已经做了良好的封装,避免了图像编解码的问题,相对使用MFC大大简化了开发逻辑,提升了开发效率。

2 C#图像读取、显示、保存模块

        代码相对简单,直接给出模块代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing.Imaging;
using System.IO;

namespace ImageProcessDemo
{
    public partial class FormMain : Form
    {
        public FormMain()
        {
            InitializeComponent();
        }

        #region  变量名字
        // 图像文件名称
        private String curFileName = null;
        // 当前图像变量
        private Bitmap curBitmap = null;
        // 原图
        private Bitmap srcBitmap = null;
        #endregion

        #region  图像打开和保存模块
        // 图像打开
        public void OpenFile()
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "所有图像文件 | *.bmp; *.pcx; *.png; *.jpg; *.gif;" +
                   "*.tif; *.ico; *.dxf; *.cgm; *.cdr; *.wmf; *.eps; *.emf|" +
                   "位图( *.bmp; *.jpg; *.png;...) | *.bmp; *.pcx; *.png; *.jpg; *.gif; *.tif; *.ico|" +
                   "矢量图( *.wmf; *.eps; *.emf;...) | *.dxf; *.cgm; *.cdr; *.wmf; *.eps; *.emf";
            ofd.ShowHelp = true;
            ofd.Title = "打开图像文件";
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                curFileName = ofd.FileName;
                try
                {
                    curBitmap = (Bitmap)System.Drawing.Image.FromFile(curFileName);
                    srcBitmap = new Bitmap(curBitmap);
                }
                catch (Exception exp)
                { MessageBox.Show(exp.Message); }
            }
        }
       
        // 图像保存
        public void SaveFile()
        {
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Filter = @"Bitmap文件(*.bmp)|*.bmp|Jpeg文件(*.jpg)|*.jpg|PNG文件(*.png)|*.png|所有合适文件(*.bmp,*.jpg,*.png)|*.bmp;*.jpg;*.png";
            sfd.FilterIndex = 3;
            sfd.RestoreDirectory = true;
            if (sfd.ShowDialog() == DialogResult.OK)
            {
                ImageFormat format = ImageFormat.Jpeg;
                switch (Path.GetExtension(sfd.FileName).ToLower())
                {
                    case ".jpg":
                        format = ImageFormat.Jpeg;
                        break;
                    case ".bmp":
                        format = ImageFormat.Bmp;
                        break;
                    case ".png":
                        format = ImageFormat.Png;
                        break;
                    default:
                        MessageBox.Show("Unsupported image format was specified!");
                        return;
                }
                pictureBox1.Image.Save(sfd.FileName, format);
            }
        }

        // 鼠标按键按下显示原图
        private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
            if (srcBitmap != null)
                pictureBox1.Image = srcBitmap;
        }

        // 鼠标按键抬起显示效果图
        private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
        {
            if (curBitmap != null)
                pictureBox1.Image = curBitmap;
        }

        // open按钮事件
        private void btn_open_Click(object sender, EventArgs e)
        {
            OpenFile();
            if (curBitmap != null)
            {
                pictureBox1.Image = (Image)curBitmap;
            }
        }

        // save按钮事件
        private void btn_save_Click(object sender, EventArgs e)
        {
            if (pictureBox1.Image != null)
                SaveFile();
        }

        #endregion
    }
}

3 C动态库图像算法模块

        构建C实现获取像素RGB值的API代码。

#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <stdio.h>

#include "ImageProcessAPI.h"

int getPixel(unsigned char *srcData, int width, int height, int stride, int x, int y, int rgba[4])
{
        x = x < 0 ? 0 : (x > width - 1 ? width - 1 : x);
        y = y < 0 ? 0 : (y > height - 1 ? height - 1 : y);
        int ret = 0;
        if(srcData == NULL)
        {
                printf("input image is null!");
                return -1;
        }
        // 图像处理,获取像素RGBA
        int pos = x * 4 + y * stride;
        rgba[0] = srcData[pos + 2];
        rgba[1] = srcData[pos + 1];
        rgba[2] = srcData[pos + 0];
        rgba[3] = srcData[pos + 3];
        return ret;
};

4 C#调用C动态库

        在C#中调用C/C++动态库需要引用 System.Runtime.InteropServices 命名空间,实例代码如下

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;

namespace ImageProcessDemo
{
    unsafe class ImageProcessBitmap
    {
        // 引用DLL中的方法,此处ImageProcessDll为DLL的名字
        [DllImport("ImageProcessDll.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.None, ExactSpelling = true)]
        // 封装C中的API接口,此处应注意C#和C之间的数据类型转换问题,所有参数的数据类型必须一致
        // getPixel为C中的接口名称
        private static extern int getPixel(byte* srcData, int width, int height, int stride, int x, int y, int[] rgba);
        // C#层接口调用
        // GetImgPixel为C#中封装的接口名称,该接口调用C中的getPixel
        public Bitmap GetImgPixel(Bitmap src, int x, int y, ref int[] rgba)
        {
            // 生成图像备份
            Bitmap a = new Bitmap(src);
            // 获取图像的宽度和高度
            int w = a.Width;
            int h = a.Height;
            // 获取并锁定图像数据区域
            // 依据图像格式可选择16/24/32位等格式
            BitmapData srcData = a.LockBits(new Rectangle(0, 0, a.Width, a.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
            // 传递给C接口
            getPixel((byte*)srcData.Scan0, w, h, srcData.Stride, x, y, rgba);
            // 解锁图像数据区域
            a.UnlockBits(srcData);
            return a;
        }
    }
}

        在C#界面中增加代码实现:用鼠标单击图像,界面上就会显示对应位置像素的RGB值。

        #region 图像处理,用鼠标单击图像,界面上就会显示对应位置像素的RGB值
        // 图像处理类
        ImageProcessBitmap imageProcess = new ImageProcessBitmap();
        // 变量
        private int[] rgba = new int[4];
        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            if (pictureBox1.Image != null)
            {
                curBitmap = imageProcess.GetImgPixel(srcBitmap, e.X, e.Y, ref rgba);
                label_rgba.Text = "RGBA: (" + rgba[0].ToString() + "," + rgba[1].ToString() + "," + rgba[2].ToString() + "," + rgba[3].ToString() + ")";
            }
        }
        #endregion

5 演示Demo

5.1 开发环境

  • Windows 10 Pro x64

  • Visual Studio 2015

5.2 功能介绍

        演示程序主界面如下图所示,具有图像读取、显示、保存以及随着光标的滑动会动态显示光标所在位置对应图像像素的RGB值等功能。

5.3 下载地址

        开发环境:

  • Windows 10 pro x64

  • Visual Studio 2015

        下载地址: 图像处理算法研究的程序框架

参考

        图像视频滤镜与人像美颜美妆算法详解. 胡耀武、谭娟、李云夕. 电子工业出版社、2020-07

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

病理AI领域基础模型及多实例学习方法的性能评估|顶刊精析·25-01-27

小罗碎碎念 这篇论文聚焦于组织学全切片图像分析&#xff0c;旨在探究多实例学习&#xff08;MIL&#xff09;与基础模型&#xff08;FMs&#xff09;结合的效果。 由于全切片图像&#xff08;WSI&#xff09;分析面临标注有限和模型直接处理困难等问题&#xff0c;MIL成为常用…

Tensor 基本操作2 理解 tensor.max 操作,沿着给定的 dim 是什么意思 | PyTorch 深度学习实战

前一篇文章&#xff0c;Tensor 基本操作1 | PyTorch 深度学习实战 本系列文章 GitHub Repo: https://github.com/hailiang-wang/pytorch-get-started 目录 Tensor 基本操作torch.max默认指定维度 Tensor 基本操作 torch.max torch.max 实现降维运算&#xff0c;基于指定的 d…

以太网详解(六)OSI 七层模型

文章目录 OSI : Open System Interconnect&#xff08;Reference Model&#xff09;第七层&#xff1a;应用层&#xff08;Application&#xff09;第六层&#xff1a;表示层&#xff08;Presentation&#xff09;第五层&#xff1a;会话层&#xff08;Session&#xff09;第四…

Spring MVC异常处理机制

文章目录 1. 异常处理的思路2. 异常处理两种方式3. 简单异常处理器SimpleMappingExceptionResolver 1. 异常处理的思路 系统中异常包括两类&#xff1a;预期异常和运行时异常RuntimeException&#xff0c;前者通过捕获异常从而获取异常信息&#xff0c;后者主要通过规范代码开发…

本地大模型编程实战(03)语义检索(2)

文章目录 准备按批次嵌入加载csv文件&#xff0c;分割文档并嵌入测试嵌入效果总结代码 上一篇文章&#xff1a; 本地大模型编程实战(02)语义检索(1) 详细介绍了如何使用 langchain 实现语义检索&#xff0c;为了演示方便&#xff0c;使用的是 langchain 提供的内存数据库。 在实…

[Dialog屏幕开发] 设置方式对话框

阅读该篇文章之前&#xff0c;可先阅读下述资料 [Dialog屏幕开发] 设置搜索帮助https://blog.csdn.net/Hudas/article/details/145381433?spm1001.2014.3001.5501https://blog.csdn.net/Hudas/article/details/145381433?spm1001.2014.3001.5501上篇文章我们的屏幕已实现了如…

【JavaEE进阶】Spring留言板实现

目录 &#x1f38d;预期结果 &#x1f340;前端代码 &#x1f384;约定前后端交互接口 &#x1f6a9;需求分析 &#x1f6a9;接口定义 &#x1f333;实现服务器端代码 &#x1f6a9;lombok介绍 &#x1f6a9;代码实现 &#x1f334;运行测试 &#x1f384;前端代码实…

1.23学习

misc buuctf-小明的保险箱 打开附件是一个在线图片首先将其另存为&#xff0c;然后仅仅只是一个图片&#xff0c;而无其他信息&#xff0c;那么我们再进行binwalk或者foremost文件分离&#xff0c;得到了一个文件夹&#xff0c;其中含有一个压缩包但是是一个加密的&#xff0…

【Python】第五弹---深入理解函数:从基础到进阶的全面解析

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】【MySQL】【Python】 目录 1、函数 1.1、函数是什么 1.2、语法格式 1.3、函数参数 1.4、函数返回值 1.5、变量作用域 1.6、函数…

【数据结构】(1)集合类的认识

一、什么是数据结构 1、数据结构的定义 数据结构就是存储、组织数据的方式&#xff0c;即相互之间存在一种或多种关系的数据元素的集合。 2、学习数据结构的目的 在实际开发中&#xff0c;我们需要使用大量的数据。为了高效地管理这些数据&#xff0c;实现增删改查等操作&…

大数据Hadoop入门2

第三部分&#xff08;Hadoop MapReduce和Hadoop YARN&#xff09; 1.课程内容-大纲-学习目标 2.理解先分再合、分而治之的思想 3.hadoop团队针对MapReduce的设计构思 map这里不能翻译成地图&#xff0c;翻译为mapping比较好一点 4.Hadoop MapReduce介绍、阶级划分和进程组成 5…

什么是BFF?他有什么用?

BFF&#xff08;Backend for Frontend&#xff09; 是一种架构模式&#xff0c;专门为前端应用提供定制化的后端服务。它的核心思想是为不同的前端客户端&#xff08;如 Web、移动端、桌面端等&#xff09;提供专门的后端服务&#xff0c;而不是让所有客户端共享同一个通用的后…

【深度之眼cs231n第七期】笔记(三十一)

目录 强化学习什么是强化学习&#xff1f;马尔可夫决策过程&#xff08;MDP&#xff09;Q-learning策略梯度SOTA深度强化学习 还剩一点小尾巴&#xff0c;还是把它写完吧。&#xff08;距离我写下前面那行字又过了好几个月了【咸鱼本鱼】&#xff09;&#xff08;汗颜&#xff…

K8S极简教程(4小时快速学会)

1. K8S 概览 1.1 K8S 是什么 K8S官网文档&#xff1a;https://kubernetes.io/zh/docs/home/ 1.2 K8S核心特性 服务发现与负载均衡&#xff1a;无需修改你的应用程序即可使用陌生的服务发现机制。存储编排&#xff1a;自动挂载所选存储系统&#xff0c;包括本地存储。Secret和…

SPDK vhost介绍

目录 1. vhost技术的背景与动机Virtio 介绍virtio-blk数据路径为例 2. vhost技术的核心原理2.1 vhost-kernel2.2 vhost-user举例 2.3 SPDK vhostvhost的优势IO请求处理数据传输控制链路调整 3. SPDK vhost的实现与配置3.1 环境准备3.2 启动SPDK vhost服务3.3 创建虚拟块设备3.4…

【C++数论】880. 索引处的解码字符串|2010

本文涉及知识点 数论&#xff1a;质数、最大公约数、菲蜀定理 LeetCode880. 索引处的解码字符串 给定一个编码字符串 s 。请你找出 解码字符串 并将其写入磁带。解码时&#xff0c;从编码字符串中 每次读取一个字符 &#xff0c;并采取以下步骤&#xff1a; 如果所读的字符是…

[创业之路-270]:《向流程设计要效率》-2-企业流程架构模式 POS架构(规划、业务运营、支撑)、OES架构(业务运营、使能、支撑)

目录 一、POS架构 二、OES架构 三、POS架构与OES架构的差异 四、各自的典型示例 POS架构典型示例 OES架构典型示例 示例分析 五、各自的典型企业 POS架构典型企业 OES架构典型企业 分析 六、各自典型的流程 POS架构的典型流程 OES架构的典型流程 企业流程架构模式…

FFmpeg音视频采集

文章目录 音视频采集音频采集获取设备信息录制麦克风录制声卡 视频采集摄像机画面采集 音视频采集 DirectShow&#xff08;简称DShow&#xff09;是一个Windows平台上的流媒体框架&#xff0c;提供了高质量的多媒体流采集和回放功能&#xff0c;它支持多种多样的媒体文件格式&…

qt-QtQuick笔记之常见项目类简要介绍

qt-QtQuick笔记之常见项目类简要介绍 code review! 文章目录 qt-QtQuick笔记之常见项目类简要介绍1.QQuickItem2.QQuickRectangle3.QQuickImage4.QQuickText5.QQuickBorderImage6.QQuickTextInput7.QQuickButton8.QQuickSwitch9.QQuickListView10.QQuickGridView11.QQuickPopu…

Autosar-Os是怎么运行的?(多核系统运行)

写在前面&#xff1a; 入行一段时间了&#xff0c;基于个人理解整理一些东西&#xff0c;如有错误&#xff0c;欢迎各位大佬评论区指正&#xff01;&#xff01;&#xff01; 目录 1.Autosar多核操作系统 1.1多核启动过程 1.2多核运行过程 1.2.1核间任务同步 1.2.2Counte…