实验7 运算符重载

实验要求

实验目的

掌握运算符重载
实现对Matrix类的运算符重载

实验内容

在之前的实验中,我们实现了矩阵类Matrix及其子类Image。本次实验我们给Matrix类添加一些重载的运算符,包括赋值运算符“=”,两个Matrix对象的“+”、“-”、“”、“/”(都是矩阵对应元素间的运算,而不是矩阵的乘除),自加自减,矩阵(或图像)对象和一个数(标量)的“=”、“+”、“-”、“”、“/”操作,判断两个矩阵(或图像)是否相等的“==”。

给Image类添加一个单目运算符“-”,作用是图像的像素值取反,即黑的变成白的,白的变成黑的。再给Image类添加一个成员函数gray2bw,该函数以给定的阈值参数把灰度图像转化为二值图像。假设图像的像素值范围在[0,1]之间的实数,给定阈值double t∈[0,1]。该函数对图像中的所有像素做如下处理:如果该像素的像素值小于t,则输出图像对应像素值赋值为0,如果该像素的像素值大于等于t,则输出图像对应像素赋值为1。此函数的输出图像对象仅含有0和1两种像素值,因此该操作在图像处理里称为“二值化”操作或“阈值分割”。
注意:这两种函数假设操作对象的数据是在[0,1]之间的实数。但是实际对象的元素数值可能不在这个范围内。因此,在这两个函数内部,需要先把所有元素的范围normalize到[0,1]区间,然后再做相应的操作。同样,在把结果保存为BMP图像的时候,要把范围再缩放到[0,255]的整数区间,注意相关的操作。

之前给大家的图片中有两幅场景图scene2_bg.bmp和scene2_fg.bmp,要求通过图像相减,再做阈值分割,分离出前景物体。

1在Matrix类中重载运算符,添加一些运算符重载函数(有的是成员函数,有的是友元函数,思考哪些适合使用成员函数,哪些适合使用友元函数?):
1)重载两个Matrix对象的赋值运算符“=”,完成类似a=b的操作。要求进行数据的深拷贝。并再次重载赋值运算符,使右操作数可以是一个double类型的数,完成矩阵所有元素赋值为该数,如a=128。
2)重载判断两个Matrix对象是否相等的“==”运算符,两个矩阵相等的条件是行列大小相同,所有元素的值也相等。
3)重载“+”运算符,针对两幅尺寸相同的矩阵,完成对应元素值相加。
4)重载“+”运算符,实现一个矩阵所有元素加上同一数值。
5)重载“-”运算符,针对两个尺寸相同的矩阵,实现对元素值相减。
6)重载“-”运算符,实现一个矩阵所有元素减去同一数值。
7)重载“”运算符,针对两个尺寸相同的矩阵,实现对元素值相乘。
8)重载“
”运算符,实现一个矩阵所有元素乘以同一数值。
9)重载“/”运算符,针对两个尺寸相同的矩阵,实现对元素值相除;自己设计除数为0时的处理办法。
10)重载“/”运算符,实现一个矩阵所有元素除以同一数值;自己设计除数为0时的处理办法。

2在Image类里,实现如下运算符和函数:
1)重载“-”单目运算符,实现一个Image对象的所有元素“取反”。
2)实现函数gray2bw,以给定的阈值对图像进行二值化,函数返回结果Image对象。
3)重载“++”运算符,实现一个矩阵所有元素自加1(分别实现前置版本和后置版本)。注意,使用该运算符的对象的像素值范围应该是[0,255],如果是[0,1]之间的,应该首先扩展到[0,255],再进行加1操作,然后再normalize回[0,1]。
4)重载“–”运算符,实现一个矩阵所有元素自减1(分别实现前置版本和后置版本)。注意,使用该运算符的对象的像素值范围应该是[0,255],如果是[0,1]之间的,应该首先扩展到[0,255],再进行加1操作,然后再normalize回[0,1]。

3在main函数中对所有实现的函数进行测试,比如前面提到的分离前景物体。
创建Image对象img1和img2,分别读入两幅图像scene2_fg和scene2_bg。新建Image对象sub,使用“-”运算符,实现img1和img2相减,并保存。对sub调用gray2bw函数进行阈值分割,保存结果。

代码示例

Matrix.h

#ifndef MATRIX_H
#define MATRIX_H

class Matrix
{
public:
// 构造函数等其它成员略

//运算符重载函数;
Matrix& operator=(const Matrix &m); //重载赋值运算符,完成对象间的深拷贝;
bool operator==(const Matrix &m); //判断两个Matrix对象是否相等

Matrix& operator++();  //前置自加;
Matrix& operator--();  //前置自减;
Matrix operator++(int);  //后置自加;

Matrix operator–(int); //后置自减;

//两个尺寸相同的矩阵,对应元素的数值相加;
friend Matrix operator+(const Matrix &m1, const Matrix &m2);
//所有元素加上同一数值;
friend Matrix operator+(Matrix &m, double num);
//两个尺寸相同的矩阵,对应元素的数值相减;
friend Matrix operator-(const Matrix &m1, const Matrix &m2);
//所有元素减去同一数值;
friend Matrix operator-(Matrix &m, double num);
//两幅尺寸相同的矩阵,对应元素的数值相乘;
friend Matrix operator*(const Matrix &m1, const Matrix &m2);
//所有元素乘上同一数值;
friend Matrix operator*(Matrix &m, double num);
//两幅尺寸相同的矩阵,对应元素的数值相除;
friend Matrix operator/( const Matrix &m1, const Matrix &m2);
//所有元素除以同一数值;
friend Matrix operator/(Matrix &m, double num);

//以上友元函数实现了Matrix对象和一个数的加减乘除,如果交换这两个操作数,即一个数和一个Matrix对象的加减乘除,应该如何做?请自行写出相关代码。

//其它成员略

};

#endif

在Image类中实现Image特有的运算符和成员函数
Image operator-(); //对图像取反,把所有像素的值都规整到[0,1]之间,然后每个像素都被1.0减
Image gray2bw(double t); //以给定阈值t对图像进行二值化,返回结果图像对象;
自加、自减的前置版本和后置版本

代码实现:

main.cpp

#include <iostream>
#include "Image.h"
#include"Matrix.h"
using namespace std;

int main(int argc, char* argv[])
{
	//写入数据
	
	Image im1("Airplane.bmp");
	im1.WriteBMP("1.bmp");
	Image im2("Baboon.bmp");
	im2.WriteBMP("2.bmp");

	
	//重载加
	Image im3(im1 + im2);
	im3.WriteBMP("3.bmp");

	//重载减
	Image im4("scene2_fg.bmp");
	Image im5("scene2_bg.bmp");
	Image im6(im4 - im5);
	im6.WriteBMP("6.bmp");

	//相等
	Image im7("Airplane.bmp");
	Image im8("Baboon.bmp");
	im7 = im8;
	im7.WriteBMP("7.bmp");
	//加上一个数
	Image im9("Fruits.bmp");
	Image im10(im9 + 400.0);
	im10.WriteBMP("10.bmp");
	//乘一个数
	Image im11("Fruits.bmp");
	Image im12(im11 * 4.0);
	im12.WriteBMP("12.bmp");
	//前置自加
	Image im13("Fruits.bmp");
	Image im14(++im13);
	im14.WriteBMP("14.bmp");
	//前置自减
	Image im15("Fruits.bmp");
	Image im16(--im15);
	im16.WriteBMP("16.bmp");
	//取反
	Image im17("Fruits.bmp");
	Image im18(-im17  );
	im18.WriteBMP("18.bmp");
	
	//阈值
	Image im19(im6.gray2bw(0.5));
	cout << 666;
	im19.WriteBMP("6.6.bmp");
	cout << 1;
	return 0;

}

image.cpp

#include "Image.h"
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;
Image::Image(int h, int w) :Matrix(h, w) {}
Image::Image(int h, int w, unsigned char val) : Matrix(h, w, val) {}//创建的图像像素值都为val;
Image::Image(const char* ImageName)//利用文件名从硬盘加载图像文件成为Image对象;
{
	ReadBMP(ImageName);
}
Image::Image(unsigned char m[][100], int rows)//从静态二维数组创建Image对象,
//图像的行数(二维数组的第一个维度)由第二个参数rows给出;
{
	height = rows;
	width = 100;
	data = new double* [height];

	for (int i = 0; i < height; i++)
	{
		data[i] = new double[width];
		for (int j = 0; j < width; j++)
		{
			data[i][j] = static_cast<unsigned char>(m[i][j]);
		}
	}
}
Image::Image(unsigned char** m, int h, int w)//从动态数组(二级指针)创建Image对象,
//图像的行数和列数由后面两个参数给出;
{
	height = h;
	width = w;
	data = new double* [height];

	for (int i = 0; i < height; i++)
	{
		data[i] = new double[width];
		for (int j = 0; j < width; j++)
		{
			data[i][j] = static_cast<unsigned char>(m[i][j]);
		}
	}
}
Image::Image(const Matrix& m) :Matrix(m) {}//构造函数重载,由Matrix类对象构造Image类对象
Image::Image(const Image& im) : Matrix(im)  //拷贝构造函数;
{
	fh = im.fh;
	ih = im.ih;
}
Image::~Image() {
	for (int i = 0; i < height; i++)
	{
		delete[] data[i];
	}
	delete[]data;
}


//从硬盘读入图像文件,存储到image类中
void Image::ReadBMP(const char* filename)
{
	FILE* fp;
	fopen_s(&fp, filename, "rb");

	fread(&fh, sizeof(fh), 1, fp);
	fread(&ih, sizeof(ih), 1, fp);

	height = ih.biHeight;
	width = ih.biWidth;

	data = new double* [height];
	for (int i = 0; i < height; i++)
	{
		data[i] = new double[width];
		for (int j = 0; j < width; j++)
		{
			unsigned char tdb[3] = { 0 };
			fread(&tdb[0], 1, 1, fp);
			fread(&tdb[1], 1, 1, fp);
			fread(&tdb[2], 1, 1, fp);

			//把三通道变为单通道,不是只保留一个通道,而是原来的三个通道都设置成一样
			data[i][j] = (static_cast<double>(tdb[0] + tdb[1] + tdb[2])) / 3;
		}
	}

	fclose(fp);
}
//保存bmp图像
void Image::WriteBMP(const char* filename)
{
	FILE* fp = NULL;
	fopen_s(&fp, filename, "wb");

	//补位
	bool flag = false;
	while (width % 4)
	{
		width++;
	}

	ih.biWidth = width;
	ih.biHeight = height;
	ih.biSizeImage = flag ?
		((((width * ih.biBitCount) + 31) / 32 * 4) * height) : width * height;

	fwrite(&fh, sizeof(fh), 1, fp);
	fwrite(&ih, sizeof(ih), 1, fp);

	unsigned char t = 0;
	for (int i = 0; i < ih.biHeight; i++)
	{
		for (int j = 0; j < ih.biWidth; j++)
		{
			t = static_cast<unsigned char>(data[i][j]);
			fwrite(&t, 1, 1, fp);
			fwrite(&t, 1, 1, fp);
			fwrite(&t, 1, 1, fp);
		}
	}

	fclose(fp);
}
Image& Image::operator=(const Image& m)
{
	for (int i = 0; i < height; i++)
	{
		for (int j = 0; j < width; j++)
		{
			this->data[i][j] = m.data[i][j];
		}
	}
	return *this;
}
Image& Image::operator+ (const Image& m1)
{

	for (int i = 0; i < height; i++)
	{
		for (int j = 0; j < width; j++)
		{
			this->data[i][j] = this->data[i][j] + m1.data[i][j];
		}
	}
	return *this;

}
Image& Image::operator- (const Image& m1)
{

	for (int i = 0; i < height; i++)
	{
		for (int j = 0; j < width; j++)
		{
			this->data[i][j] = this->data[i][j] - m1.data[i][j];
		}
	}
	return *this;

}
Image& Image::operator* (const Image& m1)
{

	for (int i = 0; i < height; i++)
	{
		for (int j = 0; j < width; j++)
		{
			this->data[i][j] = this->data[i][j] * m1.data[i][j];
		}
	}
	return *this;

}
Image& Image::operator/ (const Image& m1)
{

	for (int i = 0; i < height; i++)
	{
		for (int j = 0; j < width; j++)
		{
			this->data[i][j] = this->data[i][j] / m1.data[i][j];
		}
	}
	return *this;

}
bool Image::operator==(const Image& m)  //判断两个Matrix对象是否相等
{
	bool s = true;
	for (int i = 0; i < height; i++)
	{
		for (int j = 0; j < width; j++)
		{
			if (this->data[i][j] != m.data[i][j])
			{
				cout << "不相等" << endl;
				s = false;
				break;

			}
		}
	}
	cout << "相等" << endl;
	return s;
}

Image& Image::operator+(double num)
{
	for (int i = 0; i < height; i++)
	{
		for (int j = 0; j < width; j++)
		{
			this->data[i][j] = this->data[i][j] + num;
		}
	}
	return *this;
}
Image& Image::operator-(double num)
{
	for (int i = 0; i < height; i++)
	{
		for (int j = 0; j < width; j++)
		{
			this->data[i][j] = this->data[i][j] - num;
		}
	}
	return *this;
}
Image& Image::operator*(double num)
{
	for (int i = 0; i < height; i++)
	{
		for (int j = 0; j < width; j++)
		{
			this->data[i][j] = this->data[i][j] * num;
		}
	}
	return *this;
}
Image& Image::operator/(double num)
{
	for (int i = 0; i < height; i++)
	{
		for (int j = 0; j < width; j++)
		{
			this->data[i][j] = this->data[i][j] / num;
		}
	}
	return *this;
}


Image& Image::operator++() //前置自加;
{
	for (int i = 0; i < height; i++)
	{
		for (int j = 0; j < width; j++)
		{
			this->data[i][j] = this->data[i][j] * 2;
		}
	}
	return *this;
}
Image& Image::operator--() //前置自加;
{
	for (int i = 0; i < height; i++)
	{
		for (int j = 0; j < width; j++)
		{
			this->data[i][j] = this->data[i][j] - this->data[i][j];
		}
	}
	return *this;
}
Image Image::operator-()
{

	for (int i = 0; i < height; i++)
	{
		for (int j = 0; j < width; j++)
		{
			this->data[i][j] =1.0 -  this->data[i][j] ;
		}
	}
	
	return *this;

}

Image Image::gray2bw(double t)
{

	for (int i = 0; i < height; i++)
	{
	
		for (int j = 0; j < width; j++)
		{
		
			if (this->data[i][j] > t)
			{
				
				this->data[i][j] = 255;
			}
			else
			{
				
				this->data[i][j] = 0;
			}
		}
	}
	cout << 555;
	return *this;
	
	
}

image.h

#ifndef Image_H
#define Image_H
#include "Matrix.h"
#include "Image.h"
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstdlib>
// 针对该结构体的字节对齐问题调整对齐策略
#pragma pack(push,1)
struct BMPFILEHEADER
{
	unsigned short bfType;
	unsigned int   bfSize;
	unsigned short bfReserved1;
	unsigned short bfReserved2;
	unsigned int   bfOffBits;
};
#pragma pack(pop)

struct BITMAPINFOHEADER
{
	unsigned long    biSize;            //本结构所占用字节数 40字节
	long             biWidth;           //位图的宽度,以像素为单位
	long             biHeight;          //位图的高度,以像素为单位
	unsigned short   biPlanes;          //目标设备的级别,必须为1
	unsigned short   biBitCount;        //每个像素所需的位数,必须是1(双色)、
										//4(16色)、8(256色)或24(真彩色)之一
	unsigned long    biCompression;     //位图压缩类型,必须是 0(BI_RGB不压缩)、
										//1(BI_RLE8压缩类型)
										//2(BI_RLE压缩类型)之一
	unsigned long    biSizeImage;       //位图的大小,以字节为单位
	long             biXPelsPerMeter;   //位图水平分辨率,每米像素数
	long             biYPelsPerMeter;   //位图垂直分辨率,每米像素数
	unsigned long    biClrUsed;         //位图实际使用的颜色表中的颜色数
	unsigned long    biClrImportant;    //位图显示过程中重要的颜色数 
};

class Image : public Matrix
{
public:
	Image() {}//构造函数,创建行列都为零的Image对象
	Image(int h, int w); //构造函数重载,创建h行,w列的Image对象
	Image(int h, int w, unsigned char val); //构造函数重载,创建的图像像素值都为val;
	Image(const char* ImageName); //构造函数重载,利用文件名从硬盘加载图像文件成为Image对象;
	Image(unsigned char m[][100], int n); //构造函数重载,从静态数组创建Image对象;
	Image(unsigned char** m, int h, int w); //构造函数重载,从动态数组创建Image对象;
	Image(const Matrix& m); //构造函数重载,由Matrix类对象构造Image类对象
	Image(const Image& im); //拷贝构造函数;
	virtual ~Image(); //析构函数;

	void ReadBMP(const char* ImageName); //从硬盘文件中读入图像数据;
	void WriteBMP(const char* filename); //将图像数据保存为图像文件;

	void Flip(int code); //图像的翻转; code为0左右,1 上下;
//	void Resize(int h, int w); //图像的缩放为参数指定的大小
//	void Resize(int h, int w, int);
	void Cut(int x1, int y1, int x2, int y2);//裁剪点(x1,y1)到点(x2,y2)的图像
	void Rotate(int degree);//图像旋转的函数(旋转角度为90度的整数倍)
	double Mean();//返回图像的均值
	double Variance();//求图像的方差

	Image& operator++();  //前置自加;
	Image& operator--();  //前置自减
	Image& operator+ (const Image& m1);
	Image& operator- (const Image& m1);
	Image& operator* (const Image& m1);
	Image& operator/ (const Image& m1);


	Image& operator+(double num);
	Image& operator-(double num);
	Image& operator*(double num);
	Image& operator/(double num);


	Image& operator=(const Image& m);
	bool operator==(const Image& m);

	Image operator-();  //对图像取反,把所有像素的值都规整到[0,1]之间,然后每个像素都被1.0减
	Image gray2bw(double t); //以给定阈值t对图像进行二值化,返回结果图像对象;
	//自加、自减的前置版本和后置版本

	void Image::Resize(int h, int w)
	{
		//由于 void Resize(int h, int w, int); 放大倍数一次不能超过两倍,
		//所以这里用迭代放大来实现任意倍数放大
		int oldw = width;
		int oldh = height;
		int neww = w;
		int newh = h;



		if (ceil(neww * 1.0 / oldw) <= 2)//width满足条件,只考虑height
		{
			if (ceil(newh * 1.0 / oldh) <= 2)//height满足条件
			{
				Resize(newh, neww, 1);
			}
			else//height不满足条件
			{
				int cnt = newh / oldh;//需要循环次数
				int temph = oldh;//另暂时的h等于原来的h
				for (int i = 0; i < cnt - 1; i++)
				{
					temph += oldh;//每次加上一个原来的h,就能保证满足条件
					Resize(temph, neww, 1);
				}
				Resize(temph + (newh % oldh), neww, 1);//最后在加上多出来又不足一个h的部分
			}
		}
		else//width不满足条件
		{
			if (ceil(newh * 1.0 / oldh) <= 2)//height满足条件
			{
				int cnt = neww / oldw;
				int tempw = oldw;
				for (int i = 0; i < cnt - 1; i++)
				{
					tempw += oldw;
					Resize(newh, tempw, 1);
				}
				Resize(newh, tempw + (neww % oldw), 1);
			}
			else//height不满足条件
			{
				int cnt = newh / oldh;
				int temph = oldh;
				for (int i = 0; i < cnt - 1; i++)
				{
					temph += oldh;
					Resize(temph, oldw, 1);
				}
				Resize(temph + (newh % oldh), oldw, 1);

				cnt = neww / oldw;
				int tempw = oldw;
				for (int i = 0; i < cnt - 1; i++)
				{
					tempw += oldw;
					Resize(newh, tempw, 1);
				}
				Resize(newh, tempw + (neww % oldw), 1);
			}
		}
	}
	void Image::Resize(int h, int w, int)//图像的缩放为参数指定的大小
	{
		//记录原有的h,w
		int oldh = h;
		int oldw = w;
		//记录原来的尺寸
		int twidth = width;
		int theight = height;
		//新值与原值的差值
		int dw = static_cast<int>(fabs(twidth - w));
		int dh = static_cast<int>(fabs(theight - h));
		//插入的间隔
		if (dw < 1)//防止dw == 0
		{
			dw = 1;
		}
		if (dh < 1)
		{
			dh = 1;
		}
		int maxw = w > twidth ? w : twidth;
		int maxh = h > theight ? h : theight;
		int difw = maxw / dw;
		int difh = maxh / dh;

		//创建新数据
		double** tdata = new double* [h];
		//用i,j控制新空间的索引值
		//用prii,prij控制原空间的索引值
		for (int i = 0, prii = 0; i < h; i++)
		{
			tdata[i] = new double[w];
			if ((i + 1) % difh == 0)
			{
				if (h < theight)
				{
					prii++;//指定 增/删 行跳过
				//删除时跳过的是原空间的相应位置,而不是新空间的
				}
				else
				{
					continue;//指定 增/删 行跳过
				//增加时,跳过的是新空间的相应位置,而不是原空间的,故直接continue
				}
			}
			for (int j = 0, prij = 0; j < w; j++)
			{
				if ((j + 1) % difw == 0)
				{
					if (w < twidth)
					{
						prij++;//指定 增/删 列跳过
					}
					else
					{
						continue;
					}
				}
				tdata[i][j] = data[prii][prij];
				if (prij < twidth - 1)
					prij++;
			}
			if (prii < theight - 1)
				prii++;
		}

		//填充跳过的指定增行/列
		if (w > twidth)//先填充列
		{
			for (int i = 0; i < h; i++)
			{
				for (int j = 0; j < w; j++)
				{
					if ((j + 1) % difw == 0)
					{
						tdata[i][j] = tdata[i][j - 1];//指定 增 列填充
					}
				}
			}
		}

		if (h > theight)//再填充行
		{
			for (int i = 0; i < h; i++)
			{
				if ((i + 1) % difh == 0)//指定 增 行填充
				{
					for (int j = 0; j < w; j++)
					{
						tdata[i][j] = tdata[i - 1][j];
					}
				}
			}
		}

		//保存
		
		data = tdata;
		height = h;
		width = w;
	}

	BITMAPINFOHEADER ih;
	BMPFILEHEADER fh;
};

#endif

Matrix.cpp

#include <iostream>
#include <iomanip>
#include "Matrix.h"

using namespace std;

Matrix::Matrix() :height(0), width(0), data(NULL)
{
}
Matrix::Matrix(int h, int w)
{
	height = h;
	width = w;
	data = new double* [height];


	for (int i = 0; i < height; i++)
	{
		data[i] = new double[width];
		for (int j = 0; j < width; j++)
		{
			data[i][j] = 0;

		}
	}
}
Matrix::Matrix(int h, int w, double val)
{
	height = h;
	width = w;
	data = new double* [height];

	for (int i = 0; i < height; i++)
	{
		data[i] = new double[width];
		for (int j = 0; j < width; j++)
		{
			data[i][j] = val;
		}
	}
}
Matrix::Matrix(const Matrix& m)
{
	width = m.width;
	height = m.height;
	data = new double* [height];

	for (int i = 0; i < height; i++)
	{
		data[i] = new double[width];
		for (int j = 0; j < width; j++)
		{
			data[i][j] = m.data[i][j];
		}
	}
}
Matrix::~Matrix()
{
	
		for (int i = 0; i < height; i++)
		{
			
				delete[] data[i];
			
		}
		delete[] data;
		
	
}


void Matrix::ReadText(const char* filename) //从文本文件中读入图像数据;
{
	/*
	FILE* fp = NULL;
	fopen_s(&fp, filename, "rb");

	//读取文件头、信息头
	fread(&fh, sizeof(fh), 1, fp);
	fread(&ih, sizeof(ih), 1, fp);

	data = new unsigned char* [ih.biHeight];//相当于data[ih.biheight][ih.biwidth*3];
	for (int i = 0; i < ih.biHeight; i++)
	{
		data[i] = new unsigned char[ih.biWidth * 3];
		for (int j = 0; j < ih.biWidth * 3; j++)
		{
			fread(&data[i][j], 1, 1, fp);
		}
	}
	fclose(fp);*/
	FILE* fp = NULL;
	fopen_s(&fp, filename, "rb");

	fread(&height, sizeof(height), 1, fp);
	fread(&width, sizeof(width), 1, fp);

	data = new double* [height];

	for (int i = 0; i < height; i++)
	{
		data[i] = new double[width * 3];
		for (int j = 0; j < width; j++)
		{
			unsigned char temp[3] = { 0 };
			for (int t = 0; t < 3; t++)
			{
				fread(&temp[t], 1, 1, fp);
			}
			data[i][j * 3 + 0] = (temp[0] + temp[1] + temp[2]) / 3;
			data[i][j * 3 + 1] = (temp[0] + temp[1] + temp[2]) / 3;
			data[i][j * 3 + 2] = (temp[0] + temp[1] + temp[2]) / 3;
		}
	}

	fclose(fp);
}
void Matrix::WriteText(const char* filename) //将图像数据保存为文本文件;
{
	/* FILE* fp2 = NULL;
	fopen_s(&fp2, filename, "wb");
	fwrite(&fh, sizeof(fh), 1, fp2);
	fwrite(&ih, sizeof(ih), 1, fp2);
	for (int i = 0; i < ih.biHeight; i++)
	{
		fwrite(data[i], ih.biWidth * 3, 1, fp2);
	}
	fclose(fp2);*/
	FILE* fp = NULL;
	fopen_s(&fp, filename, "wb");

	fwrite(&height, sizeof(height), 1, fp);
	fwrite(&width, sizeof(width), 1, fp);

	for (int i = 0; i < height; i++)
	{
		for (int j = 0; j < width; j++)
		{
			fwrite((unsigned char*)&data[i][j], sizeof(unsigned char), 1, fp);
		}
	}

	fclose(fp);
}
Matrix& Matrix::operator=(const Matrix& m)
{
	for (int i = 0; i < height; i++)
	{
		for (int j = 0; j < width; j++)
		{
			this->data[i][j] = m.data[i][j];
		}
	}
	return *this;
}

Matrix& Matrix::operator+(const Matrix& m1)
{
	
	for (int i = 0; i < height; i++)
	{
		for (int j = 0; j < width; j++)
		{
			this->data[i][j] = this->data[i][j] + m1.data[i][j];
		}
	}
	return *this;
	
}
Matrix& Matrix::operator-(const Matrix& m1)
{
	for (int i = 0; i < height; i++)
	{
		for (int j = 0; j < width; j++)
		{
			this->data[i][j] = this->data[i][j] - m1.data[i][j];
		}
	}
	return *this;
}
Matrix& Matrix::operator*(const Matrix& m1)
{
	for (int i = 0; i < height; i++)
	{
		for (int j = 0; j < width; j++)
		{
			this->data[i][j] = this->data[i][j] * m1.data[i][j];
		}
	}
	return *this;
}
Matrix& Matrix::operator/(const Matrix& m1)
{
	for (int i = 0; i < height; i++)
	{
		for (int j = 0; j < width; j++)
		{
			this->data[i][j] = this->data[i][j] / m1.data[i][j];
		}
	}
	return *this;
}
bool Matrix::operator==(const Matrix& m)  //判断两个Matrix对象是否相等
{
	bool s = true;
	for (int i = 0; i < height; i++)
	{
		for (int j = 0; j < width; j++)
		{
			if (this->data[i][j] != m.data[i][j])
			{
				cout << "不相等"<<endl;
				s = false;
				break;

		}
		}
	}
	cout << "相等" << endl;
	return s;
}

 Matrix& Matrix::operator+( double num)
{
	for (int i = 0; i < height; i++)
	{
		for (int j = 0; j < width; j++)
		{
			this->data[i][j] = this->data[i][j] + num;
		}
	}
	return *this;
}
 Matrix& Matrix::operator-(double num)
 {
	 for (int i = 0; i < height; i++)
	 {
		 for (int j = 0; j < width; j++)
		 {
			 this->data[i][j] = this->data[i][j] - num;
		 }
	 }
	 return *this;
 }
 Matrix& Matrix::operator*(double num)
 {
	 for (int i = 0; i < height; i++)
	 {
		 for (int j = 0; j < width; j++)
		 {
			 this->data[i][j] = this->data[i][j] * num;
		 }
	 }
	 return *this;
 }

 Matrix& Matrix::operator/(double num)
 {
	 for (int i = 0; i < height; i++)
	 {
		 for (int j = 0; j < width; j++)
		 {
			 this->data[i][j] = this->data[i][j] / num;
		 }
	 }
	 return *this;
 }

 Matrix& Matrix::operator++() //前置自加;
 {
	 for (int i = 0; i < height; i++)
	 {
		 for (int j = 0; j < width; j++)
		 {
			 this->data[i][j] = this->data[i][j]*2;
		 }
	 }
	 return *this;
 }
 Matrix& Matrix::operator--() //前置自减;
 {
	 for (int i = 0; i < height; i++)
	 {
		 for (int j = 0; j < width; j++)
		 {
			 this->data[i][j] = this->data[i][j] - this->data[i][j];
		 }
	 }
	 return *this;
 }

Matrix.h

#ifndef MATRIX_H
#define MATRIX_H

class Matrix
{
public:
    Matrix();
    Matrix(int h, int w);
    Matrix(int h, int w, double val);
    Matrix(const Matrix& m);
    virtual ~Matrix();
    void str(int h, int w);
    void ReadText(const char* filename); //从文本文件中读入图像数据;
    void WriteText(const char* filename); //将图像数据保存为文本文件;

    void Zeros(int h, int w); // 根据参数产生h行w列的全零矩阵
    void Ones(int h, int w); // 根据参数产生h行w列的全1矩阵
    void Random(int h, int w); //产生h行w列的随机矩阵,矩阵的元素为[0,1]之间的随机实数(double类型)
    void Identity(int n); // 根据参数产生n行n列的单位矩阵

    int Height() { return height; }  // 获得矩阵的行数
    int Width() { return width; }   // 获得矩阵的列数
    double& At(int row, int col); //获取第row行第col列的矩阵元素的值
    void Set(int row, int col, double value); //设置第row行第col列矩阵元素的值为value
    void Set(double value); //设置矩阵所有元素为同一值value

//运算符重载函数;
    Matrix& operator=(const Matrix& m);  //重载赋值运算符,完成对象间的深拷贝;
    bool operator==(const Matrix& m);  //判断两个Matrix对象是否相等

    Matrix& operator++();  //前置自加;
    Matrix& operator--();  //前置自减;
    Matrix operator++(int);  //后置自加;
    Matrix operator--(int);  //后置自减;

    //两个尺寸相同的矩阵,对应元素的数值相加;
    Matrix& operator+(const Matrix& m1);//两个尺寸相同的矩阵,对应元素的数值相加;
   //两个尺寸相同的矩阵,对应元素的数值相减;
    Matrix& operator-(const Matrix& m1);
    //两幅尺寸相同的矩阵,对应元素的数值相乘;
    Matrix& operator*(const Matrix& m1);
    //两幅尺寸相同的矩阵,对应元素的数值相除;
   Matrix& operator/(const Matrix& m1);



    //所有元素加上同一数值;
     Matrix& operator+( double num);
    //所有元素减去同一数值;
     Matrix& operator-(double num);
    //所有元素乘上同一数值;
     Matrix& operator*(double num);
    //所有元素除以同一数值;
     Matrix& operator/(double num);
   

     void Matrix::Normalize()
     {
         double max = 0;
         double min = 0;
         for (int i = 0; i < height; i++)
             for (int j = 0; j < width; j++)
                 if (data[i][j] > max)
                     max = data[i][j];
         for (int i = 0; i < height; i++)
             for (int j = 0; j < width; j++)
                 if (data[i][j] < min)
                     min = data[i][j];
         for (int i = 0; i < height; i++)
             for (int j = 0; j < width; j++)
                 data[i][j] = (data[i][j] - min) / (max - min);
     }
     void Matrix::Reshape(int h, int w)
     {
         double** a = new double* [1000];
         for (int i = 0; i < 1000; i++)
             a[i] = new double[1000];
         for (int i = 0; i < h; i++)
             for (int j = 0; j < w; j++)
             {
                 int c = (i * w + j) / width;
                 int d = (i * w + j) % width;
                 a[i][j] = data[c][d];
             }
         for (int i = 0; i < height; i++)
             delete[]data[i];
         delete[]data;
         data = new double* [h];
         for (int i = 0; i < h; i++)
             data[i] = new double[w];
         for (int i = 0; i < h; i++)
             for (int j = 0; j < w; j++)
                 data[i][j] = a[i][j];
         for (int i = 0; i < 1000; i++)
             delete[]a[i];
         delete[]a;
         height = h;
         width = w;
     }

    //其它成员略
    int height;
    int width;
    double** data;
};

#endif

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值