zoukankan      html  css  js  c++  java
  • FreeImage使用基础,图像旋转,图像滤波

    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(); }
  • 相关阅读:
    AJAX
    Aliyun服务器配置Redis
    Aliyun服务器配置MySQL
    Python基础之迭代器详解
    Python基础之函数
    Flask入门--URL
    认识Web
    肖知兴:企业的底层逻辑与企业家的突破(下)
    建造者模式(Bulider模式)详解
    为什么我强烈推荐你用枚举来实现单例模式
  • 原文地址:https://www.cnblogs.com/wangshide/p/2470693.html
Copyright © 2011-2022 走看看