freeImage图像旋转滤波

2023-11-19

原文:http://www.cnblogs.com/wangshide/archive/2012/04/25/2470693.html
1. 使用了 freeImage 图像库进行图像读取,保存(如何将图片转为矩阵,如何处理图片的颜色(rgb),透明等信息)

2. 图像旋转

3. 高斯图像滤波


#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include "FreeImage.h"
#include <math.h>
#include <time.h>
#pragma comment(lib, "FreeImage.lib")

#define  PI  3.141592645
// 自定义一个4字节的结构体
class byte4
{
public:
    BYTE r; // 用于存放 red
    BYTE g; // 用于存放 green
    BYTE b; // 用于存放 blue
    BYTE a; // 用于存放 alpha
};

static int maskHeight = 3; // 掩模高度
static int maskWidth  = 3; // 掩模宽度
//高斯滤波掩模
float mask[3][3] = 
    {
    {0.0751 ,  0.1238  , 0.0751},
    {0.1238 ,  0.2042  , 0.1238},
    {0.0751 ,  0.1238  ,  0.0751}};
//串行图像滤波
void cpu_filter(byte4** inbuf,  byte4** outbuf, int w, int h)
{
    for(int row = 1; row < h - 1; row ++)
    {
        for(int col = 1; col < w - 1; col ++)
        {
            outbuf[row][col].r = 0;
            outbuf[row][col].g = 0;
            outbuf[row][col].b = 0;
            outbuf[row][col].a = 0;
            float t1 = 0, t2 = 0, t3 = 0, t4 = 0;
            for(int i = 0; i < maskHeight; i ++)
                for(int j = 0; j < maskWidth; j++)
                {
                     t1 += inbuf[row + i - 1][col + j - 1].r * mask[i][j];
                     t2 += inbuf[row + i - 1][col + j - 1].g * mask[i][j];
                     t3 += inbuf[row + i - 1][col + j - 1].b * mask[i][j];
                     t4 += inbuf[row + i - 1][col + j - 1].a * mask[i][j];
                }

            outbuf[row][col].r = (int)t1;
            outbuf[row][col].g = (int)t2;
            outbuf[row][col].b = (int)t3;
            outbuf[row][col].a = (int)t4;
        }
    }
}
//CPU旋转图像
void cpu_rotate(byte4** inbuf, byte4** outbuf, int w, int h, float angle)
{
    if(w % 2 == 0) w --;
    if(h % 2 == 0) h --;
    int i, j;
    int xc = w/2;
    int yc = h/2;

    float cosTheta = cos(PI * angle/180);
    float sinTheta = sin(PI * angle/180);

    for(i = 0; i < h; i++)
    {
        for(j=0; j< w; j++)
        {
            int xpos = (int)( (i-xc)*cosTheta  + (j-yc)*sinTheta + xc );    
            int ypos = (int)( -(i-xc)*sinTheta + (j-yc)*cosTheta + yc ); 

            if(xpos>=0 && ypos>=0 && xpos<h && ypos < w )
                outbuf[xpos][ypos] = inbuf[i][j];
        }
    }
}
void main(int argc, char* argv)
{


    char * imageFile = "lenna.PNG";
    // 初始化
    FreeImage_Initialise(TRUE);

    // 读取图像
    FIBITMAP * bitmap = FreeImage_Load(FIF_PNG, imageFile, PNG_DEFAULT);
    if(bitmap) printf("Image Load successfully!\n");
    // 获得图像的宽和高(像素)
    int width  = FreeImage_GetWidth(bitmap);
    int height = FreeImage_GetHeight(bitmap);
    // 计算每个像素的字节数
    /************************************************************************/
    /* 已经测试有JPEG格式:每像素字节数3                                      */
    /* 已经测试有JPEG格式:每像素字节数4                                      */
    /************************************************************************/
    int bytespp = FreeImage_GetLine(bitmap)/ width;
    printf("Width:%d\t Height:%d\t 每像素字节数:%d\n", width, height, bytespp);



    // 测试 int, float, byte4的各自的字节数
    printf("int: %d \nfloat: %d\nbyte4: %d\n", sizeof(int), sizeof(float), sizeof(byte4));

    // 用于存放像素值得矩阵
    byte4 **matrix;
    // 动态开辟2维数组
    matrix = (byte4 **)calloc(height, sizeof(byte4*));
    for(int i = 0; i < height; i++)
    {
        matrix[i] = (byte4*)calloc(width, sizeof(byte4));
    }
    // 用于存放输出像素值矩阵
    byte4 ** matrix_dst;
    // 动态开辟2维数组
    matrix_dst = (byte4 **)calloc(height, sizeof(byte4*));
    for(int i = 0; i < height; i++)
    {
        matrix_dst[i] = (byte4*)calloc(width, sizeof(byte4));
    }
    if(matrix && matrix_dst)
        printf("内存申请成功!\n");

    for(unsigned y = 0; y < height; y++)
    {
        BYTE *bitsLine = FreeImage_GetScanLine(bitmap, y);
        for(unsigned x = 0; x < width; x++)
        {
            // 设置像素颜色
            matrix[y][x].r = bitsLine[FI_RGBA_RED]   ;
            matrix[y][x].g = bitsLine[FI_RGBA_GREEN] ;
            matrix[y][x].b = bitsLine[FI_RGBA_BLUE]  ;
            matrix[y][x].a = bitsLine[FI_RGBA_ALPHA] ;
            bitsLine += bytespp;            
        }
    }

    // 执行旋转, 滤波
    int start = clock();
    // cpu_rotate(matrix, matrix_dst, width, height, 90);
    cpu_filter(matrix, matrix_dst, width, height);
    printf("Time elapsed: %d ms\n", (clock() - start));

    // 输出FreeImage 图像
    FIBITMAP * dst =  bitmap;

    for(unsigned y = 0; y < height; y++)
    {
        BYTE *bitsLine = FreeImage_GetScanLine(dst, y);
        for(unsigned x = 0; x < width; x++)
        {
            // 设置像素颜色
            bitsLine[FI_RGBA_RED]   = matrix_dst[y][x].r ;
            bitsLine[FI_RGBA_GREEN] = matrix_dst[y][x].g ;
            bitsLine[FI_RGBA_BLUE]  = matrix_dst[y][x].b ;
            bitsLine[FI_RGBA_ALPHA] = matrix_dst[y][x].a ;
            bitsLine += bytespp;
        }
    }

    // 存储图像
    FreeImage_Save(FIF_PNG, dst, "dst.png", PNG_DEFAULT);
    getchar();
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

freeImage图像旋转滤波 的相关文章

  • Python 基础(一):入门必备知识

    目录 1 标识符 2 关键字 3 引号 4 编码 5 输入输出 6 缩进 7 多行 8 注释 9 数据类型 10 运算符 10 1 常用运算符 10 2 运算符优先级 基础 进阶 爬虫 自动化 数据分析 编写小游戏 趣味 Python 文档
  • ajax xhr参数无法接收到,AJAX XHR-Call会创建无效的参数异常

    所以我尝试从异步任务 在此处未显示 因为它不相关 我认为它工作 中的值通过Jquery xhr请求放入进度条中 服务器端的方法并不相关 因为它的工作方式和jquery xhr call都可以 仅限第一次 AJAX XHR Call会创建无效
  • Rasa中文聊天机器人开发指南(3):Core篇

    文章目录 1 对话管理1 1 多轮对话1 2 对话管理 2 Rasa Core 2 1 Stories 2 2 Domain 2 3 Responses 2 4 Actions 2 5 Policies 2 6 Slots 2 6 1 Sl
  • nvm-use成功,但是实际并没有切换到对应node版本

    nvm use命令行运行成功 但是nvm list显示并没有成功 解决方案 情况描述 说明 使用nvm安装完node版本成功之后 nvm list显示并没有切换成功 node v使用的不是use版本 原因 因为在安装nvm之前 独自安装了一
  • rtsp协议c语言,RTSP协议

    RTSP简介 RTSP Real Time Streaming Protocol 是由Real Network和Netscape共同提出的如何有效地在IP网络上传输流媒体数据的应用层协议 RTSP对流媒体提供了诸如暂停 快进等控制 而它本身
  • 浏览器无法加载本地文件

    问题描述 在Visual Studio Code 编写HTML文件时需要将 csv文件内容在浏览器控制台窗口输出 浏览器控制一直报错 如下图所示 原因 跨域资源共享问题 本地文件是放在file 这样的系统下 而非网络资源比如http 下 造
  • Matlab实现PID控制仿真(附上30个完整仿真源码+数据)

    本文介绍了如何使用Matlab实现PID控制器的仿真 首先 我们将简要介绍PID控制器的原理和控制算法 然后 我们将使用Matlab编写一个简单的PID控制器 并使用仿真环境来验证其性能 最后 我们将通过调整PID控制器的参数来优化控制系统
  • LVGL笔记7--lv_label标签控件

    LVGL笔记7 lv label标签控件 lv label标签控件是LVGL中使用最频繁的控件 主要是用来显示文本信息的 可在程序运行中动态修改文本内容 支持换行显示 图标字体 部分文本重绘色 长文本显示 6种显示模式等功能 lv labe
  • 八段数码管动态显示(输入数据为BCD编码)

    八段数码管动态显示 输入数据为BCD编码 一 数码管概述 图1 八段共阴数码管内部等效原理图 图2 八段共阳数码管内部等效原理图 上面两图分别是对应八段共阴 共阳的数码管内部等效图 共阴是将八个LED数码管的阴极连接在一起接低 阳极segm
  • Docker系列01—容器的发展历程---Docker的生态圈

    Docker 和容器技术的发展可谓是日新月异 本文试图以全局的视角来梳理一下 docker 目前的生态圈 既然是概览 所以不会涉及具体的技术细节 Docker 自从发布以来发生了很多的变化 并且有些方面的变化还非常大 对于技术爱好者来说 我

随机推荐

  • 【模电】0017 开关电源的原理及分析

    开关电源一般简称为DCDC 比我们前两节分析的线性电源复杂一些 它与线性电源最大的不同在于其调整管的工作状态 开关电源中的调整管工作在开关状态 即只工作在饱和区和截止区 1 典型开关电源的原理 一个典型的降压型开关电源原理如下图 首先 我们
  • 前端代理配置

    dev env require dev env port process env PORT 8080 autoOpenBrowser true assetsSubDirectory static assetsPublicPath proxy
  • 海量影像图元合并可以考虑用openmp

    影像合并图元耗时较长 又是重复的功能 可以考虑并行openmp
  • Linux测试比较语句

    测试和比较语句用于if或脚本命令中 if condition then commands else if conditon then commands fi 或 condition command 如果condition为真则执行comma
  • [ 数据结构-C语言 ] 二叉树--初阶 大总结~~

    今天要和大家一起步入一个新的数据结构 二叉树 在学习了解二叉树之前我们先来了解什么是树 以下是本篇的主要内容及目录 目录 1 树的概念及其结构 1 1树的概念 1 2树的相关概念 重点 1 3树的表示 2 二叉树概念及结构 2 1概念 2
  • 优化算法 - BGD、MBGD、SGD - 梯度下降

    优化算法 BGD MBGD SGD 梯度下降 BGD SGD MBGD BGD BGD Batch Gradient Descent 批量梯度下降 损失函数 L X
  • 管道-阻塞与非阻塞

    非阻塞的管道和FIFO 管道和FIFO都可以设置非阻塞 它们两者都可以在打开之后通过fcntl函数设置O NONBLOCK标志来enable 一般而言 我们都是先使用F GETFL来获取当前文件状态标志 将它与O NONBLOCK按位或之后
  • javatServlet中的cookie设置

    cookie 服务器将一些信息存储在浏览器 本地 当用户再次打开网页时 会自动填充该信息 当浏览器再次发送请求时 会将存储的信息通过请求头的方式发送给服务器端 不需要用户每次都填充某些内容 cookie中理论上来讲 最大存储4KB内容 co
  • 数学界的扫地僧们(转)

    转载连接 http www newsmth net nForum article WorkLife 752660 前两天跟一个老同学聊近年来数学上的重大发现 结果作为科普人的我说着说着就发现 数学史原来就是一部八卦史 这个圈子奇葩辈出 怪事
  • C中violatile的用法

    1 violate影响编译器结果的输出 violate变量随时可能发生变化 与violate有关的运算不要进行编译优化 以免出错 例如 volatile int i 10 int j i int k i violate告诉编译器变量i是随时
  • 对接微信支付(二)统一下单API

    原创文章 对接微信支付 二 统一下单API 编程屋 大家可以先想一下 大家平时在PC端发起的支付都需要什么 是不是你选好商品之后 点击支付 然后PC端弹出来一个二维码 你扫码付款 付款完成之后就OK了 当然这只是针对我们用户来说的 对于我们
  • 什么是数字孪生技术?

    数字孪生是实体对象的虚拟模型 它跨越对象的生命周期 并使用从对象上的传感器发送的实时数据来模拟行为并监控操作 数字孪生可以复制许多现实世界中的物品 从工厂中的单台设备到完整的装置 例如风力涡轮机 甚至整个城市 数字孪生技术使您能够监督资产的
  • 毕业设计-基于机器视觉深度学习船只船舶检测

    目录 前言 课题背景和意义 实现技术思路 实现效果图样例 前言 大四是整个大学期间最忙碌的时光 一边要忙着备考或实习为毕业后面临的就业升学做准备 一边要为毕业设计耗费大量精力 近几年各个学校要求的毕设项目越来越难 有不少课题是研究生级别难度
  • Idea设置maven依赖自动导入

    maven自动导入 setting gt Build gt Build Tools gt Any changes
  • mmocr环境配置

    win10 显卡3070 创建名为mmocr的环境 conda create n mmocr python 3 7 y 激活mmocr conda activate mmocr 失败了 安装完事竟然是cpu版本 没找到原因 本人3070显卡
  • SpringBoot 图片上传(详解篇)

    前言 SpringBoot在服务器内上传文件 是临时文件 在重启时候会生成另外的目录 也就意味着原来上传的图片在重启后就访问不到了 1 图片上传 PostMapping upload public CommonResult insertDb
  • [人工智能-深度学习-77]:目标检测 - 常见项目、应用

    作者主页 文火冰糖的硅基工坊 文火冰糖 王文兵 的博客 文火冰糖的硅基工坊 CSDN博客 本文网址 https blog csdn net HiWangWenBing article details 122307915 目录 前言 场景一
  • 【Golang入门】Golang第一天心得

    生活所迫 入门一下Go 很奇葩的第一点 接口 package main import fmt 定义一个接口 type Shape interface Area float64 定义一个矩形类型 type Rectangle struct W
  • 企业级体验:未来体验管理的价值与趋势

    我从事企业级体验相关领域的工作已十六载有余 曾经就职的企业既有阿里巴巴 腾讯这样的互联网 大厂 也有顺丰 龙湖这样的线下 传统 企业 在这些企业中 我所工作的场景横跨了软件 电商 互联网 物流 零售 地产 金融等诸多业务领域 为不同业务场景
  • freeImage图像旋转滤波

    原文 http www cnblogs com wangshide archive 2012 04 25 2470693 html 1 使用了 freeImage 图像库进行图像读取 保存 如何将图片转为矩阵 如何处理图片的颜色 rgb 透