精华内容
下载资源
问答
  • 3. 将上述实现的函数封装为c++的一个类 ex.hpp: # ifndef _EX_HPP_ # define _EX_HPP_ # include "../CImg.h" # include # include using namespace std ; using namespace cimg_library ; ...

    1. CImg的配置

    • 下载CImg的包到指定的文件夹下,解压
    • 然后只需要在编写的cpp或hpp文件中加入
    #include "XX/CImg.h" // XX/是指CImg所在的路径
    using namespace cimg_library;
    
    
    • 编译命令(环境为windows下的MinGW
    g++ -o HelloWorld.exe HelloWorld.cpp -O2 -lgdi32
    

    2.简单使用

    1. 读入1.bmp 文件

    CImg<unsigned char> SrcImg;
    SrcImg.load_bmp("1.bmp");
    

    2. 用CImg.display() 显示

    void test_display(CImg<unsigned char> SrcImg) {
    	SrcImg.display("work1");
    }
    

    这里写图片描述

    3. 把1.bmp文件的白色区域变成红色,黑色区域变成绿色

    void test_change(CImg<unsigned char> SrcImg) {
    	CImg<unsigned char> Img = SrcImg;
    	cimg_forXY(Img, x, y) {
    		if (Img(x,y,0) == 255 && Img(x,y,1) == 255 && Img(x,y,2) == 255) {
    			Img(x,y,0) = 255;
    			Img(x,y,1) = 0;
    			Img(x,y,2) = 0;
     		}
    	}
    	cimg_forXY(Img, x, y) {
    		if (Img(x,y,0) == 0 && Img(x,y,1) == 0 && Img(x,y,2) == 0) {
    			Img(x,y,0) = 0;
    			Img(x,y,1) = 255;
    			Img(x,y,2) = 0;
     		}
    	}
    	Img.display("work2");
    }
    

    这里写图片描述

    4. 在图上绘制一个圆形区域,圆心坐标(50,50),半径为30,填充颜色为蓝色

    • 未使用CImg的接口函数
    void DrawCircle_blue1(CImg <unsigned char> TempImg) {
    	CImg<unsigned char> SrcImg = TempImg;
    	cimg_forXY(SrcImg, x, y) {
    		if (pow(pow(x-50,2)+pow(y-50,2),0.5) < 30) {
    			SrcImg(x,y,0) = 0;
    			SrcImg(x,y,1) = 0;
    			SrcImg(x,y,2) = 255;
    		}
    	}
    	SrcImg.display("work3.1");
    }
    

    这里写图片描述

    • 使用接口函数draw_circle()
    void DrawCircle_blue2(CImg <unsigned char> TempImg) {
    	unsigned char blue[] = {0,0,255};
    	TempImg.draw_circle(50, 50, 30, blue);
    	TempImg.display("work3.2");
    }
    

    这里写图片描述

    PS: 这个感觉自己实现的算法和接口函数实现的效果差不多

    5. 在图上绘制一个圆形区域,圆心坐标(50,50),半径为3,填充颜色为黄色

    • 未使用CImg的接口函数
    void DrawCircle_yellow1(CImg <unsigned char> TempImg) {
    	CImg<unsigned char> SrcImg = TempImg;
    	cimg_forXY(SrcImg, x, y) {
    		if (pow(pow(x-50,2)+pow(y-50,2),0.5) < 3) {
    			SrcImg(x,y,0) = 200;
    			SrcImg(x,y,1) = 155;
    			SrcImg(x,y,2) = 0;
    		}
    	}
    	SrcImg.display("work4.1");
    }
    ![这里写图片描述](https://img-blog.csdn.net/20180911172544111?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3BlcnJ5MDUyOA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
    

    这里写图片描述

    • 使用接口函数draw_circle()
    void DrawCircle_yellow2(CImg <unsigned char> TempImg) {
    	unsigned char yellow[] = {200, 155, 0};
    	TempImg.draw_circle(50, 50, 3, yellow);
    	TempImg.display("work4.2");
    }
    

    这里写图片描述

    PS: 这个虽然接口函数的效果也并不是特别好,但是明显比我的要好很多,但是因为遍历图片的像素点是对图片进行采样所以点坐标为整数值,圆的半径越小意味着我们取的像素点范围越少,点越少,所以图片的效果会较差,甚至接近正方形,可能接口的函数有更好的实现方法,尝试去翻了翻源码没太看懂

    6. 在图上绘制一条长为100的直线段,起点坐标为(0, 0),方向角为35度,直线的颜色为蓝色

    • 未使用CImg的接口函数
    void DrawLine1(CImg <unsigned char> TempImg) {
    	CImg<unsigned char> SrcImg = TempImg;
    	double x0 = 100*cos(35*pi/180);
    	double y0 = 100*sin(35*pi/180);
    	cimg_forXY(SrcImg, x, y) {
    		if (x == 0) {
    			if (y == 0) {
    				SrcImg(x,y,0) = 0;
    				SrcImg(x,y,1) = 0;
    				SrcImg(x,y,2) = 255;
    			}
    		}
    		else {
    			if (cmp((double)y, (double)x*tan(35*pi/180)) && (double)x <= x0 && (double)y <= y0) {
    				SrcImg(x,y,0) = 0;
    				SrcImg(x,y,1) = 0;
    				SrcImg(x,y,2) = 255;
    			}
    		}
    	}
    	SrcImg.display("work5.1");
    }
    
    //用于上面函数的一个辅助函数,来判断相等条件
    bool cmp(double x , double y) { //compare x and y,如果差值小于一定范围则近似相等
    	if (abs(x - y) <= 0.5)
    		return 1;
    	return 0;
    }
    

    这里写图片描述

    • 使用接口函数draw_line()
    void DrawLine2(CImg <unsigned char> TempImg) {
    	unsigned char blue[] = {0,0,255};
    	TempImg.draw_line(0,0,100*cos(35*pi/180),100*sin(35*pi/180),blue);
    	TempImg.display("work5.2");
    }
    
    

    这里写图片描述

    PS: 这个比较效果感觉肉眼很难看出差距,但是因为遍历图片的像素点是对图片进行采样所以点坐标为整数值,所以不可能存在彻底等于所得的浮点数tan角要求的坐标,只能通过设置误差尽可能小,也就是直线的粗细,通过设置cmp函数调节几个值(0.1, 0.3, 0.5, 1.0)发现0.5的效果是最好的。

    7. 把上面的操作结果保存为 2.bmp

    SrcImg.save("2.bmp");
    

    3. 将上述实现的函数封装为c++的一个类

    ex.hpp:

    #ifndef _EX_HPP_
    #define _EX_HPP_
    #include "../CImg.h"
    #include <cmath>
    #include <string>
    using namespace std;
    using namespace cimg_library;
    const double pi(3.14159265);
    class Test
    {
    	public:
    		Test();
    		~Test();
    		void Todisplay();
    		void change(); //把1.bmp文件的白色区域变成红色,黑色区域变成绿色
    		void DrawCircle_blue1(); //不使用CImg函数在图上绘制一个圆形区域,圆心坐标(50,50),半径为30,填充颜色为蓝色
    		void DrawCircle_yellow1();//不使用CImg函数在图上绘制一个圆形区域,圆心坐标(50,50),半径为3,填充颜色为黄色
    		void DrawLine1();//不使用CImg函数 在图上绘制一条长为100的直线段,起点坐标为(0, 0),方向角为35度,直线的颜色为蓝色。 
    		//下面三个函数分别对应使用CImg函数的上述三个操作
    		void DrawCircle_blue2();
    		void DrawCircle_yellow2();
    		void DrawLine2();
    		CImg<unsigned char> getSrcImg();
    	private:
    		//string name; //图片的名称
    		CImg<unsigned char> SrcImg; //定义一副图片
    };
    #endif
    

    ex.cpp

    #include "ex.hpp"
    using namespace std;
    bool cmp(double x , double y);
    
    Test::Test() {
    	//name = "work1";
    	SrcImg.load_bmp("1.bmp");
    }
    
    Test::~Test() {}
    
    void Test::Todisplay() {
    	//string t = name;
    	SrcImg.display("homework");
    }
    
    CImg<unsigned char> Test::getSrcImg() {
    	return SrcImg;
    }
    
    void Test::change() {
    	//name = "work2";
    	//CImg<unsigned char> Img = SrcImg;
    	cimg_forXY(SrcImg, x, y) {
    		if (SrcImg(x,y,0) == 255 && SrcImg(x,y,1) == 255 && SrcImg(x,y,2) == 255) {
    			SrcImg(x,y,0) = 255;
    			SrcImg(x,y,1) = 0;
    			SrcImg(x,y,2) = 0;
     		}
    	}
    	cimg_forXY(SrcImg, x, y) {
    		if (SrcImg(x,y,0) == 0 && SrcImg(x,y,1) == 0 && SrcImg(x,y,2) == 0) {
    			SrcImg(x,y,0) = 0;
    			SrcImg(x,y,1) = 255;
    			SrcImg(x,y,2) = 0;
     		}
    	}
    }
    
    void Test::DrawCircle_blue1() {
    	cimg_forXY(SrcImg, x, y) {
    		if (pow(pow(x-50,2)+pow(y-50,2),0.5) < 30) {
    			SrcImg(x,y,0) = 0;
    			SrcImg(x,y,1) = 0;
    			SrcImg(x,y,2) = 255;
    		}
    	}
    }
    
    void Test::DrawCircle_yellow1() {
    	cimg_forXY(SrcImg, x, y) {
    		if (pow(pow(x-50,2)+pow(y-50,2),0.5) < 3) {
    			SrcImg(x,y,0) = 200;
    			SrcImg(x,y,1) = 155;
    			SrcImg(x,y,2) = 0;
    		}
    	}
    }
    
    void Test::DrawLine1() {
    	double x0 = 100*cos(35*pi/180);
    	double y0 = 100*sin(35*pi/180);
    	cimg_forXY(SrcImg, x, y) {
    		if (x == 0) {
    			if (y == 0) {
    				SrcImg(x,y,0) = 0;
    				SrcImg(x,y,1) = 0;
    				SrcImg(x,y,2) = 255;
    			}
    		}
    		else {
    			if (cmp((double)y, (double)x*tan(35*pi/180)) && (double)x <= x0 && (double)y <= y0) {
    				SrcImg(x,y,0) = 0;
    				SrcImg(x,y,1) = 0;
    				SrcImg(x,y,2) = 255;
    			}
    		}
    	}
    }
    
    void Test::DrawCircle_blue2() {
    	unsigned char blue[] = {0,0,255};
    	SrcImg.draw_circle(50, 50, 30, blue);
    }
    
    void Test::DrawCircle_yellow2() {
    	unsigned char yellow[] = {200, 155, 0};
    	SrcImg.draw_circle(50, 50, 3, yellow);
    }
    		
    void Test::DrawLine2() {
    	unsigned char blue[] = {0,0,255};
    	SrcImg.draw_line(0,0,100*cos(35*pi/180),100*sin(35*pi/180),blue);
    }
    
    bool cmp(double x , double y) { //compare x and y,如果差值小于一定范围则近似相等
    	if (abs(x - y) <= 0.5)
    		return 1;
    	return 0;
    }
    

    main.cpp

    #include "ex.hpp"
    using namespace std;
    int main(int argc, char const *argv[])
    {
    	Test pic;
    	Test pic1;
    	pic.change();
    	pic.DrawCircle_blue1();
    	pic.DrawCircle_yellow1();
    	pic.DrawLine1();
    	pic.Todisplay();
    	CImg<unsigned char> temp = pic.getSrcImg();
    	temp.save("2.bmp");
    	pic1.change();
    	pic1.DrawCircle_blue2();
    	pic1.DrawCircle_yellow2();
    	pic1.DrawLine2();
    	pic1.Todisplay();
    	CImg<unsigned char> temp1 = pic1.getSrcImg();
    	temp1.save("2.1.bmp");
    	return 0;
    }
    

    运行并存储后实现的整体效果图如下所示:
    (1) 未使用接口函数:
    这里写图片描述
    (2) 使用接口函数:
    这里写图片描述

    完整代码参见:
    https://github.com/WangPerryWPY/Computer-Version/tree/master/EX1

    展开全文
  • CImg 库是一个免费、开源的图像处理C++库,名称原意是 Cool Image,正如其名,CImg是一个非常优秀、功能强大、代码简洁、使用方便的C++ 图像处理库。它不仅非常适合科学家、研究生做科研时使用,也适合在工业应用...

     

    CImg 库是一个免费、开源的图像处理C++库,名称原意是 Cool Image,正如其名,CImg是一个非常优秀、功能强大、代码简洁、使用方便的C++ 图像处理库。它不仅非常适合科学家、研究生做科研时使用,也适合在工业应用工程开发中使用,更适合的是,对于有志于开发简洁、高效、功能强大的图像处理库的人而言,CImg的源码是不可多得的学习和参考资料。

      

    CImg 官网:http://cimg.sourceforge.net/

    CImg论坛:http://sourceforge.net/projects/cimg/forums/forum/334630

     

    总体而言,CImg 有以下特征:

     

    功能强大:使用CImg, 可以读取和存储各种格式的图像文件,可以访问像素值,可以显示、变换、及对图像进行各种滤波,在图像上画图像元素(字符串、多边形、3-d 物体...),计算图像的各种统计信息,处理人机交互等等...

     

    普适性:CImg只定义了一个模板类来表征任何不超过4-d 的数据集,并且元素类型可以是绝大多数C++内置类型和自定义类型(bool, char, int, float...). CImg 还可以处理图像集合和图像序列。

     

    可移植性:它完全兼容于操作系统如Windows, Unix, Linux, MacOS X, *BSD...,也完全兼容与编译器如 VC++, g++, icc...等,具有高度的可移植性。

     

    轻便性:CImg 非常轻便,整个库只用一个文件:cimg.h。任何C++应用程序只需要将该头文件包含进工程中即可使用该库的全部功能。它只定义了四了类(模板)和两个名称空间。该库只依赖与标准C++和STL,只在显示类部分依赖与操作系统的GDI,再也不依赖任何其他的外部库。

     

    可扩展性:CImg 使用两种机制来增强其功能,这两种机制都不是必须的,只是锦上添花,可以增加一些功能。一是利用外部工具或库的功能,比如:ImageMagick,GraphicsMagick,XMedCon,FFMPEG, libpng, libjpeg, libtiff, Magick++, OpenCV, Lapack, Board, OpenEXR or FFTW3;二是使用插件的机制,可以使库的使用者自行扩展库的功能。

     

    自由性:完全免费、开源、可以用于商业开发。

     

    跟OpenCV相比,CImg 虽然提供了基本上所有的图像处理的基本操作,但图像处理的高级操作较少,因此总体上功能比OpenCV少很多,(因为OpenCV 本身很庞大,包括基本上所有的图像处理基本操作,还包含了大量的图像处理高级操作,而且还包含了模式识别的东西)。但CImg对有志于开发图像处理库的人而言,具有很大的研究价值,因为该库结构简单,代码简洁高效,功能相对已经很强大,且代码量不大(40,000多行),编程技巧很有大师风格。 当然,如果研究者水平极高,有能力研究OpenCV源码的,则另当别论。

     

     

     

    展开全文
  • C++ 图像处理常用

    2020-03-04 21:00:19
    OpenGL 渲染管线流程为:顶点数据 -> 顶点着色器 -> 图元装配 -> 几何着色器 -> 光栅化 -> 片段着色器 -> 逐片段处理 -> 帧缓冲 GPU上与渲染处理对应的GPU硬件包括: 顶点处理: Vertex Shader(顶点着色器) 纹理帖...


    一、 OpenCL (Open Computing Language)

    parallel programming of diverse accelerators (including multi-core CPUs, GPUs, DSPs, FPGAs and dedicated hardware such as inferencing engines.

    进行并行计算的low-levelAPI,可直接控制硬件。

    在Deeplearning中,对应卷积等科学计算,硬件为GPU和DL Accelerators.

    参考:https://www.khronos.org/opencl/

    二、 OpenGL

    使用GPU进行图形渲染,用于生成2D、3D图像。

    OpenGL 渲染管线流程为:顶点数据 -> 顶点着色器 -> 图元装配 -> 几何着色器 -> 光栅化 -> 片段着色器 -> 逐片段处理 -> 帧缓冲

    GPU上与渲染处理对应的GPU硬件包括:

    • 顶点处理: Vertex Shader(顶点着色器)
    • 纹理帖图:TMU(Texture mapping unit)
    • 光栅化引擎ROP

    参考:https://www.jianshu.com/p/92208a75283d

     

    三、 OpenGL ES

    OpenGL for Embedded Systems,用于嵌入式的图形渲染API,是OpenGL的子集,仅保留了高效的函数。

    OpenGL® ES is a royalty-free, cross-platform API for rendering advanced 2D and 3D graphics on embedded and mobile systems - including consoles, phones, appliances and vehicles. It consists of a well-defined subset of desktop OpenGL suitable for low-power devices, and provides a flexible and powerful interface between software and graphics acceleration hardware.

    参考: https://www.jianshu.com/p/b92b39df57e5

     

    四、 GLFW

    OpenGL / OpenGL ES 是跨平台的,它只专注渲染; 其他内容在每个平台上都要有它的具体实现,比如上下文环境和窗口的管理就交由各个设备自己来完成。

    GLFW is an Open Source, multi-platform library for OpenGL, OpenGL ES and Vulkan application development. It provides a simple, platform-independent API for creating windows, contexts and surfaces, reading input, handling events, etc.

    五、 EGL

    EGL™ is an interface between Khronos rendering APIs such as OpenGL ES or OpenVG and the underlying native platform window system.

    EGL 是 OpenGL ES 渲染 API 和本地窗口系统(native platform window system)之间的一个中间接口层。

     

    六、Eigen: 矩阵运算

    Eigen is a C++ template library for linear algebra: matrices, vectors, numerical solvers, and related algorithms.

    https://eigen.tuxfamily.org/dox/group__QuickRefPage.html

     

    LodePNG:

    PNG encoder and decoder in C and C++, without dependencies
    例如把PNG图像解码为RGBA/RGB,或者将PNG图像解码为RGBA/RGB像素数据;
    Convert PNG to BMP或Convert BMP to PNG。

     

    滤波Filter(low-pass, high-pass and band-pass FIR filter):

    https://cardinalpeak.com/blog/a-c-class-to-implement-low-pass-high-pass-and-band-pass-filters/

     

    绘制线图Plot

    matplotlib-cpp works by wrapping the popular python plotting library matplotlib.

    https://github.com/lava/matplotlib-cpp

    展开全文
  • C++图像处理类库

    2018-04-03 12:04:45
    GIFLIB 是一个 C 语言的 Gif 图像处理库。支持 Gif 图像读写。 如果需要单独处理某类图片格式,以上类库是比较好的选择,如果处理的格式种类比较多,下面的类库是比较好的选择。    2. freeimage C语言的...
    1. GIFLIB 是一个 C 语言的 Gif 图像处理库。支持 Gif 图像读写。

    如果需要单独处理某类图片格式,以上类库是比较好的选择,如果处理的格式种类比较多,下面的类库是比较好的选择。

       2. freeimage

    C语言的体系,大量使用指针运算速度可以保证,内含先进的多种插值算法。
    另外独有的支持meta exif信息的读取。该库最大的特点就是比较简练,只把重点放在对各种格式图像的读取写入支持上,没有显示部分,实际编程的时候还是需要调用API函数进行显示。

       3. ImageMagick

    ImageMagick 是一个用来创建、编辑、合成图片的软件。它可以读取、转换、写入多种格式的图片。图片切割、颜色替换、各种效果的应用,图片的旋转、组合,文本,直线, 多边形,椭圆,曲线,附加到图片伸展旋转。ImageMagick是免费软件:全部源码开放,可以自由使用,复制,修改,发布。支持大多数的操作系统。 有很多命令行工具非常好用。

       4. GD
    GD 是一个开源的图像处理库,支持 PNG/JPEG/GIF以及其他格式的图像。GD一般被用来创建图表、图形、缩略图以及其他图像相关的处理操作。
    GD安装参考

       5. The CImg Library
    The CImg Library是一个强大的图像处理类库。在代码中使用此类可以导入/导出,处理,和显示图片,它是一个强大的处理图像的C++工具箱。

       6. DiffImg
    DiffImg 是一个简单的图像比较工具,可用来比较相同尺寸的两个 RGB 图像,并提供两个图像的差异比较数据。

       7. ExactImage
    ExactImage 是一个快速的 C++ 图像处理库,与 ImageMagick 不同的是,ExactImage 允许对多个色彩空间和色深进行操作;更低的内存占用和CPU占用;某些优化算法速度是 ImageMagick 的 20 倍,显示大图片的速度是 ImageMagick 的 10 倍。
    相关参考

    展开全文
  • c++图像处理入门教程

    千次阅读 多人点赞 2019-07-30 14:53:27
    最近有人问我图像处理怎么研究,怎么入门,怎么应用,我竟一时语塞。仔细想想,自己也搞了两年图像方面的研究,做个两个创新项目,发过两篇论文,也算是有点心得,于是总结总结和大家分享,希望能对大家有所帮助。在...
  • 【1】配置环境 电脑配置:w764+vs2017+opencv4.3.0 解决方案配置:debug+x64(注意c++中的配置环境要和c#中的环境保持一致) 【2】实现思路 (1)c#中读入一个图片的路径。...步骤参考:C#调用c++图像处理库(Op..
  • Symbian c++调用opencv进行图像处理

    千次阅读 2009-11-03 13:42:00
    毕论要在手机端利用sift算法提取图像特征值,而Lowa给出的sift是基于...nokia官方给出了nokiacv的图像处理库,封装了图像转换、拉普拉斯算子卷积等函数,但毕竟功能有限,除此之外的函数都需自己实现,觉得有些郁郁
  • C#调用C++图像处理算法(opencv)

    千次阅读 2018-03-21 23:54:26
    C#调用C++图像处理算法(OpenCV) 因为需要做一个图像处理的程序,后来决定采用C#写界面,C++写算法调用opencv的函数。关于opencv的使用之前已经学习过了,需要实现的是在C#中如何使用C++语言编写的DLL。 参考:...
  • C++图像处理函数及程序(一)

    千次阅读 2019-03-10 16:47:06
    CxImage :用于加载,保存,显示和转换的图像处理和转换,可以处理的图片格式包括 BMP, JPEG, GIF, PNG, TIFF, MNG, ICO, PCX, TGA, WMF, WBMP, JBG, J2K。 FreeImage :开源,支持现在多媒体应用所需的通用图片...
  • c++ 图像处理类库

    千次阅读 2013-07-02 15:10:46
    如果需要单独处理某类图片格式,以上类库是比较好的选择,如果处理的格式种类比较多,下面的类库是比较好的选择。 ImageMagick ImageMagick 是一个用来创建、编辑、合成图片的软件。它可以读取、转换、写入多种...
  • 对比度拉伸变换对图像进行对比度拉伸变换,压缩动态范围,将我们所关注的边界特征信息详细化,从而使得输出图像亮区域更亮,暗区域更暗,提高了图像的对比度。 opencv中的 LUT函数(look up table)为查表函数, ...
  • C++图像处理 -- 线性亮度/对比度调整

    万次阅读 多人点赞 2009-08-28 14:36:00
    阅读提示: 《C++图像处理》系列以代码清晰,可读性为主,全部使用C++代码。 《Delphi图像处理》系列以效率为侧重点,一般代码为PASCAL,核心代码采用BASM。 尽可能保持二者内容一致,可相互对照。 本文代码必须...
  • Java服务器部署基于OpenCV的C++图像处理项目(一) 由于最近项目需要在后台处理图片并返回结果给移动端,所以折腾了一周如何将c++代码和opencv打包并部署到java服务器中供后台调用,这里记录下详细过程。 基础环境...
  • 欢迎大家访问我的github:https://github.com/Iamttp 有问题欢迎在评论留言呀! ... 2020/2/5更新: VS2019/VS2017 OpenCv配置: VS对于C++配置外部有两种方式,另一种写在了后面,这里介绍的是新建配置...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 57,489
精华内容 22,995
关键字:

c++图像处理库

c++ 订阅