图像处理:c++读取.raw图像、c++下旋转和resize处理、c++下梯形畸变校正、c++下更改图像尺寸及pixelSpacing

图像处理:c++读取.raw图像、c++下旋转和resize处理、c++下梯形畸变校正、c++下更改图像尺寸及pixelSpacing
1. c++读取.raw图像
本人拿到的图像是1024*1024尺寸的,读取该类型图像时,需知图像宽度、高度、像素格式(如8位灰度、16位灰度等)和数据排列方式。
读取代码如:

const int width = 1024;
	const int height = 1024;
	const std::string file_path = "D://image.raw";

// 1. 读取文件
	std::ifstream file(file_path, std::ios::binary | std::ios::ate);
	if (!file) {
		std::cerr << "文件打开失败!" << std::endl;
		return -1;
	}

size_t file_size = file.tellg();
	file.seekg(0);
	std::vector<uint8_t> buffer(file_size);
	file.read(reinterpret_cast<char*>(buffer.data()), file_size);
	file.close();

// 2. 转换为 16 位像素
	std::vector<uint16_t> pixels(width * height);
	std::memcpy(pixels.data(), buffer.data(), file_size);

// 3. 转换为 OpenCV 图像并显示
	cv::Mat image(height, width, CV_16UC1, pixels.data());
	
//取反
	cv::Mat image_inverse(image.cols, image.cols, CV_16UC1);
	for (int i = 0; i < image.cols; i++)
	{
		for (int j = 0; j < image.cols; j++)
		{
			image_inverse.at<ushort>(i, j) = 65535 - image.at<ushort>(i, j);
		}
	}
	cv::imshow("Image", image_inverse);
	cv::waitKey(0);

2. c++下旋转和resize处理
以上读取的图像存在旋转角度,并且尺寸太大,需要对图像进行旋转和resize处理。
处理代码如下:

//旋转90°
	cv::Mat image_inverse_rotate;
	cv::transpose(image_inverse, image_inverse_rotate);
	cv::flip(image_inverse_rotate, image_inverse_rotate, 0);
	
//resize为512*512
	cv::Mat image_inverse_rotate_resize;
	cv::resize(image_inverse_rotate, image_inverse_rotate_resize, cv::Size(512, 512));
	cv::imshow("Image", image_inverse_rotate_resize);
	cv::waitKey(0);

3. c++下梯形畸变校正
以上获取到的图像存在一定的畸变(梯形畸变),需要对其进行校正,通过同时调整四个点,将图像从一种视角变换到另一种视角。主要有三个步骤:
a、定义源点和目标点:
-----源点是原始图像的四个角点。
-----目标点是变换后图像的四个角点。
b、计算变换矩阵:
-----根据源点和目标点计算透视变换矩阵。
c、应用变换:
-----将变换矩阵应用到原始图像上,得到校正后的图像,然后再根据自己想要的尺寸进行裁剪。
代码如下:

// 定义梯形区域的四个角点(假设已知)
    std::vector<cv::Point2f> srcPoints;
    srcPoints.push_back(cv::Point2f(50, 78));  // 左上角
    srcPoints.push_back(cv::Point2f(400, 78));  // 右上角
    srcPoints.push_back(cv::Point2f(404, 234));  // 右下角
    srcPoints.push_back(cv::Point2f(30, 234));   // 左下角

   // 定义校正后的矩形区域的四个角点
    std::vector<cv::Point2f> dstPoints;
    dstPoints.push_back(cv::Point2f(30, 78));      // 左上角
    dstPoints.push_back(cv::Point2f(404,78));    // 右上角
    dstPoints.push_back(cv::Point2f(404, 234));  // 右下角
    dstPoints.push_back(cv::Point2f(30, 234));    // 左下角

   // 计算透视变换矩阵
    cv::Mat perspectiveMatrix = cv::getPerspectiveTransform(srcPoints, dstPoints);

   // 应用透视变换
    cv::Mat dst;
    cv::warpPerspective(src, dst, perspectiveMatrix, cv::Size(414, 313));

   // 显示结果
    cv::imshow("Source Image", src);
    cv::waitKey(0);
    cv::imshow("Corrected Image", dst);
    cv::waitKey(0);

4. c++下更改图像尺寸及pixelSpacing
为了满足需求,需要更改图像尺寸和像素分辨率,原图像的分辨率伟0.308,要求转为0.4
代码如下:

//进行pixel的修改
	double original_spacing = 0.308;
	double target_spacing = 0.4;
	int new_width = static_cast<int>(Dstimage.rows * target_spacing / original_spacing);
	int new_height = new_width;

// 使用双线性插值放大图像
	Mat resized_img_newResoltion;
	cv::resize(Dstimage, resized_img_newResoltion, cv::Size(new_width, new_height), 0, 0, cv::INTER_LINEAR);

附:
关键概念(例)
–1.像素分辨率:
----a.0.976单位/像素:表示每个像素的物理尺寸伟0.976×0.976单位(如mm)
----b.0.5单位/像素:表示目标分辨率下,每个像素的物理尺寸更小(图像更“密集”)
–2.物理尺寸与像素尺寸的关系:
----a.原始物理尺寸:28 × 0.976 = 27.328 单位。
----b.目标物理尺寸:28 × 0.5 = 14.0 单位。
----c.矛盾点:如果保持 28×28 像素不变,物理尺寸会缩小(从 27.328 → 14.0 单位),这本质上是 提高了图像的分辨率密度(单位距离内像素更多)

若目标是保持物理内容不变修改分辨率标签(不实际插值像素),只需更新图像的元数据(如 DICOM 中的 Pixel Spacing 字段)。
若需 物理内容适配新分辨率,则需要通过插值调整图像尺寸(但会改变像素矩阵大小)。

方法 1:仅修改分辨率标签(不改变像素数据)
代码如下:

// 假设原始图像是 28x28,分辨率为 0.976
 cv::Mat image = cv::Mat::zeros(28, 28, CV_8UC1); // 示例图像
// 修改分辨率标签(OpenCV 本身不存储分辨率,需借助其他库如 DCMTK)
double new_spacing = 0.5; // 目标分辨率
// 通常需要保存为 DICOM 或自定义格式时更新元数据
std::cout << "修改后的分辨率: " << new_spacing << " unit/pixel" << std::endl;
return 0;

方法 2:通过插值调整物理内容(改变像素矩阵)
如果目标是 保持物理尺寸 27.328 单位 但 分辨率改为 0.5 单位/像素,则需重新计算像素矩阵大小:
计算目标像素尺寸:
新宽度 = 原始物理宽度 / 新分辨率 = 27.328 / 0.5 ≈ 55 像素
新高度 = 原始物理高度 / 新分辨率 = 27.328 / 0.5 ≈ 55 像素
使用 resize() 插值放大图像到 55×55 像素。
代码如下:

 cv::Mat src = cv::Mat::zeros(28, 28, CV_8UC1); // 示例图像
//计算新尺寸(保持物理尺寸不变)
    double original_spacing = 0.976;
    double target_spacing = 0.5;
    int new_width = static_cast<int>(28 * original_spacing / target_spacing); // ≈55
    int new_height = new_width;
 // 使用双线性插值放大图像
    cv::Mat dst;
    cv::resize(src, dst, cv::Size(new_width, new_height), 0, 0, cv::INTER_LINEAR);
std::cout << "新图像尺寸: " << dst.size() << std::endl;
   return 0;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值