图像读取和显示以及像素操作

  • Visual Studio 相关配置
  • CImg.h的使用课参考以下网址
  • 1. 读入1.bmp文件,并用CImg.display() 显示。
  • 2.把1.bmp文件的白色区域变成红色,黑色区域变成绿色
  • 3. 在图上绘制一个等边三角形区域,其中心坐标(50,50),边长为40,填充颜色为 蓝色
  • 4.在图上绘制一个圆形区域,圆心坐标(50,50),半径为15,填充颜色为黄色。
  • 5.在图上绘制一条长为100的直线段,起点坐标为(0, 0),方向角为135度,直线 的颜色为绿色。
  • 6.把上面的操作结果保存为2.bmp。


Visual Studio 相关配置

计算机视觉小程序开发 计算机视觉应用开发 1+x_#include


将相关的文件先放到文件夹里,头文件CImg.h和图片1.bmp

在VS里添加头文件

计算机视觉小程序开发 计算机视觉应用开发 1+x_#include_02


VS新建项目用C++的空项目即可

CImg.h的使用课参考以下网址

https://www.e-learn.cn/content/qita/1360910

1. 读入1.bmp文件,并用CImg.display() 显示。

代码如下:

#include "CImg.h"

using namespace cimg_library;

int main() {
   CImg<unsigned char> photo("1.bmp");
   photo.display();
   return 0;
}

结果:

计算机视觉小程序开发 计算机视觉应用开发 1+x_计算机视觉小程序开发_03


第一步完成

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

代码如下:

#include "CImg.h"

using namespace cimg_library;

int main() {
	CImg<unsigned char> photo("1.bmp");
	//1. 读入1.bmp文件,并用CImg.display() 显示
	//photo.display();

	//2. 把1.bmp文件的白色区域变成红色,黑色区域变成绿色。 
	cimg_forXY(photo,x,y) { //对所有坐标进行遍历
		//白色的rgb值为(255,255,255)变成红色(255,0,0)
		if (photo(x, y, 0) == 255 && photo(x, y, 1) == 255 && photo(x, y, 2) == 255)
			photo(x, y, 1) = photo(x, y, 2) = 0;
		//黑色rgb值为(0,0,0)变成绿色(0,255,0)
		if (photo(x, y, 0) == 0 && photo(x, y, 1) == 0 && photo(x, y, 2) == 0)
			photo(x, y, 1) = 255;
	}
	photo.display();
	return 0;
}

结果如下:

计算机视觉小程序开发 计算机视觉应用开发 1+x_#include_04

3. 在图上绘制一个等边三角形区域,其中心坐标(50,50),边长为40,填充颜色为 蓝色

代码如下:

//3.在图上绘制一个等边三角形,中心坐标(50,50),边长为40,填充颜色为蓝色。
	//创建空图像,参数分别为height,width,depth,spectrum
	CImg<unsigned char> photo(400, 400, 1, 3);
	//填充黑色
	photo.fill(0);
	//求出三个顶点的坐标A,B,C
	int Ax = 50;
	int Ay = 50 - 20 / cos(PI/6);
	int Bx = 50 - 20;
	int Cx = 50 + 20;
	int By, Cy;
	By = Cy = 50 + 20 * tan(PI/6);
	//三条直线的斜率与截距,对于三角形内的点进行计算
	double kbc = (Cy - By)*1.0 / (Cx - Bx);
	double lbc = By*1.0 - kbc * Bx;
	double kab = (By - Ay)*1.0 / (Bx - Ax);
	double lab = Ay*1.0 - kab * Ax;
	double kac = (Cy - Ay)*1.0 / (Cx - Ax);
	double lac = Cy*1.0 - kac * Cx;
	printf("\nkbc:%lf, kab:%lf, kac:%lf", kbc, kab, kac);
	printf("\nlbc:%lf, lab:%lf, lac:%lf", lbc, lab, lac);
	int x = 0, y = 0;
	cimg_forXY(photo,x,y){
		//直线y=kx+l,即y-kx-l
		double dab = y - kab * x - lab;
		double dbc = y - kbc * x - lbc;
		double dac = y - kac * x - lac;
		//printf("x:%d,y:%d,dab:%d, dbc:%d, dac:%d\n", x, y, dab, dbc, dac);
		//在区域内满足以下条件
		if (dab>=0 && dbc<=0 && dac>=0) {
			photo(x, y, 2) = 255;
		}
	}
	photo.display();

结果如下:

计算机视觉小程序开发 计算机视觉应用开发 1+x_#include_05

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

代码如下:

int main() {
	//4. 在图上绘制一个圆形区域,圆心坐标(50, 50),半径为15,填充颜色为黄色。
	CImg<unsigned char> photo(400, 400, 1, 3);
	//填充黑色
	photo.fill(0);
	cimg_forXY(photo, x, y) {
		double x2 = (x - 50)*(x - 50);
		double y2 = (y - 50)*(y - 50);
		//在圆内部,涂成黄色(255,255,0)
		if (x2 + y2 <= 900)
			photo(x, y, 0) = photo(x, y, 1) = 255;
	}
	photo.display();
	return 0;
}

结果如下:

计算机视觉小程序开发 计算机视觉应用开发 1+x_ci_06

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

代码如下

int main(){
// 5.在图上绘制一条长为100的直线段,起点坐标为(0, 0),方向角为135度,直线 的颜色为绿色。
	CImg<unsigned char> photo(400, 400, 1, 3);
	photo.fill(0);
	int count = 0;
	cimg_forXY(photo, x, y) {
		if (x == y) {
			photo(x, y, 1) = 255;
			count++;
		}
		if (count >= 100) break;
	}
	photo.display();
}

结果如下:

计算机视觉小程序开发 计算机视觉应用开发 1+x_ci_07

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

汇总代码(有部分更改):

int main() {
   //1. 读入1.bmp文件,并用CImg.display() 显示
   CImg<unsigned char> photo("1.bmp");

   //2. 把1.bmp文件的白色区域变成红色,黑色区域变成绿色。 
   cimg_forXY(photo, x, y) { //对所有坐标进行遍历
   						  //白色的rgb值为(255,255,255)变成红色(255,0,0)
   	if (photo(x, y, 0) == 255 && photo(x, y, 1) == 255 && photo(x, y, 2) == 255)
   		photo(x, y, 1) = photo(x, y, 2) = 0;
   	//黑色rgb值为(0,0,0)变成绿色(0,255,0)
   	if (photo(x, y, 0) == 0 && photo(x, y, 1) == 0 && photo(x, y, 2) == 0)
   		photo(x, y, 1) = 255;
   }

   //3.在图上绘制一个等边三角形,中心坐标(50,50),边长为40,填充颜色为蓝色。
   //求出三个顶点的坐标A,B,C
   int Ax = 50;
   int Ay = 50 - 20 / cos(PI / 6);
   int Bx = 50 - 20;
   int Cx = 50 + 20;
   int By, Cy;
   By = Cy = 50 + 20 * tan(PI / 6);
   //三条直线的斜率与截距,对于三角形内的点进行计算
   double kbc = (Cy - By)*1.0 / (Cx - Bx);
   double lbc = By * 1.0 - kbc * Bx;
   double kab = (By - Ay)*1.0 / (Bx - Ax);
   double lab = Ay * 1.0 - kab * Ax;
   double kac = (Cy - Ay)*1.0 / (Cx - Ax);
   double lac = Cy * 1.0 - kac * Cx;
   int x = 0, y = 0;
   cimg_forXY(photo, x, y) {
   	//直线y=kx+l,即y-kx-l
   	double dab = y - kab * x - lab;
   	double dbc = y - kbc * x - lbc;
   	double dac = y - kac * x - lac;
   	//printf("x:%d,y:%d,dab:%d, dbc:%d, dac:%d\n", x, y, dab, dbc, dac);
   	//在区域内满足以下条件
   	if (dab >= 0 && dbc <= 0 && dac >= 0) {
   		photo(x, y, 0) = photo(x, y, 1) = 0;
   		photo(x, y, 2) = 255;
   	}
   }

   //4. 在图上绘制一个圆形区域,圆心坐标(50, 50),半径为15,填充颜色为黄色。
   cimg_forXY(photo, x, y) {
   	double x2 = (x - 50)*(x - 50);
   	double y2 = (y - 50)*(y - 50);
   	//在圆内部,涂成黄色(255,255,0)
   	if (x2 + y2 <= 900) {
   		photo(x, y, 0) = photo(x, y, 1) = 255;
   		photo(x, y, 2) = 0;
   	}	
   }

   // 5.在图上绘制一条长为100的直线段,起点坐标为(0, 0),方向角为135度,直线 的颜色为绿色。
   int count = 0;
   cimg_forXY(photo, x, y) {
   	if (x == y) {
   		photo(x, y, 0) = photo(x, y, 2) = 0;
   		photo(x, y, 1) = 255;
   		count++;
   	}
   	if (count >= 100) break;
   }
   photo.display();
   photo.save("2.bmp");
   return 0;
}

汇总结果:

计算机视觉小程序开发 计算机视觉应用开发 1+x_ci_08


蓝色区域被黄色覆盖