博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
数字图像处理学习笔记(1.1)---位图的读写、几何变换、傅里叶变换、直方图均衡...
阅读量:7224 次
发布时间:2019-06-29

本文共 4399 字,大约阅读时间需要 14 分钟。

图像的几何变换

#include"bmp.h"#include
#include
#include
#include
using namespace std;void Bitmap::translation(int offsetX, int offsetY)//平移变换{if (dataBuf == NULL)cout << "请确保已经读入图像数据!" << endl;int w, h;//长宽的循环变量int k;//像素通道的循环变量int pixelByte = bitCount / 8;//每像素的字节数int lineByte = (width_p*bitCount / 8 + 3) / 4 * 4;//每行像素的字节数unsigned char* transBuf = new unsigned char[height_p*lineByte];//分配数据存储空间memset(transBuf, 0, height_p*lineByte);//置为黑色//平移运算for (h = 0; h < height_p; h++){for (w = 0; w < width_p; w++){//输出的点在输入的点范围内if (h - offsetY >= 0 && h - offsetY <= height_p&&w - offsetX >= 0 && w - offsetX <= width_p){for (k = 0; k < pixelByte; k++){*(transBuf + h*lineByte + w*pixelByte + k)= *(dataBuf + (h - offsetY)*lineByte + (w - offsetX)*pixelByte + k);}}}}delete[] dataBuf;dataBuf = transBuf;//释放原数据内存,指向变换后的图像数据cout << "平移成功!" << endl;}void Bitmap::zoom(float ratioX, float ratioY, char interpolationWay = 'n')//缩放变换{switch (interpolationWay){case 'n':neighborInterpolation(ratioX, ratioX);break;case 'l':dbLinearInterpolatin(ratioX, ratioY);break;case 'c':cubicConvoInterpolatin(ratioX, ratioY);break;default:break;}}void Bitmap::neighborInterpolation(float ratioX, float ratioY){int pixelByte = bitCount / 8;//每像素字节数int widthOut = int(ratioX*width_p);//输出图像宽度和高度int heightOut = int(ratioY*height_p);int lineByte = (width_p*bitCount / 8 + 3) / 4 * 4;//原图像每行像素的字节数int lineByteOut = (widthOut*bitCount / 8 + 3) / 4 * 4;//变换后图像每行像素的字节数unsigned char* transBuf = new unsigned char[lineByteOut*heightOut];memset(transBuf, 0, lineByteOut*heightOut);int w, h;int k;//输出图像对应在输入图像中待插值的位置坐标int coordinateX, coordinateY;for (h = 0; h < heightOut; h++){for (w = 0; w < widthOut; w++){//输出图像(w,h)处像素映射到原图像中的坐标值,即插值坐标coordinateX = int(w / ratioX + 0.5);coordinateY = int(h / ratioY + 0.5);//若插值位置在输入图像范围内,则近邻插值if (coordinateX >= 0 && coordinateX <= width_p&&coordinateY >= 0 && coordinateY <= height_p){for (k = 0; k < pixelByte; k++){*(transBuf + h*lineByteOut + w*pixelByte + k)= *(dataBuf + coordinateY*lineByte + coordinateX*pixelByte + k);}}}}delete[] dataBuf;dataBuf = transBuf;}void Bitmap::dbLinearInterpolatin(float ratioX, float ratioY){int pixelByte = bitCount / 8;//每像素字节数int widthOut = int(ratioX*width_p);//输出图像宽度和高度int heightOut = int(ratioY*height_p);int lineByte = (width_p*bitCount / 8 + 3) / 4 * 4;//原图像每行像素的字节数int lineByteOut = (widthOut*bitCount / 8 + 3) / 4 * 4;//变换后图像每行像素的字节数unsigned char* transBuf = new unsigned char[lineByteOut*heightOut];int w, h;int k;//输出图像对应在输入图像中待插值的位置坐标float coordinateX, coordinateY;//临时变量,待插值位置向下取整的坐标int Iu, Iv;//数组,存放插值位置周围的4个像素unsigned char array[2][2];//双线性插值for (h = 0; h< heightOut; h++){for (w = 0; w< widthOut; w++){//输出图像坐标为(j,i)的像素映射到原图中的坐标值,即插值位置coordinateX = w / ratioX;coordinateY = h / ratioY;//对插值位置坐标取整Iu = (int)coordinateX;Iv = (int)coordinateY;//若插值位置在输入图像范围内,则双线性插值if (0 <= coordinateX&&coordinateX
= 0 && coordinateY
255)t = 255;//调用双线性插值函数插值并输出到transBuf中*(transBuf + h * lineByteOut + w*pixelByte + k) = t;}}else{//边缘像素采用近邻插值for (k = 0; k
= 1 && coordinateY
= 0 && t<1)col[i] = pow(t, 3) - 2 * pow(t, 2) + 1;else if (t >= 1 && t<2)col[i] = -pow(t, 3) + 5 * pow(t, 2) - 8 * t + 4;elsecol[i] = 0;}//对垂直方向系数数组进行计算for (i = 0; i<4; i++){t = fabs(row[i]);if (t >= 0 && t<1)row[i] = pow(t, 3) - 2 * pow(t, 2) + 1;else if (t >= 1 && t<2)row[i] = -pow(t, 3) + 5 * pow(t, 2) - 8 * t + 4;elserow[i] = 0;}//将计算好的系数与对应图像数据数组作卷积float tempArray[4], temp;//先x方向卷积for (i = 0; i<4; i++)tempArray[i] = row[0] * array[0][i] + row[1] * array[1][i] + row[2] * array[2][i] + row[3] * array[3][i];//再y方向卷积temp = 0;for (i = 0; i<4; i++)temp += tempArray[i] * col[i];//将插值结果在图像灰度级范围内输出if (temp>255)temp = 255;if (temp<0)temp = 0;//调用立方卷积插值函数插值并输出到transBuf中*(transBuf + h * lineByteOut + w*pixelByte + k) = (unsigned char)temp;}}else{//边缘像素采用近邻插值for (k = 0; k
= 0) && (coordinateX <= width_p) && (coordinateY >= 0)&& (coordinateY <=height_p)){//将图像每个通道的数据进行分别插值,彩色图像pixelByte为3,//灰度图像pixelByte为1for (k = 0; k
测试

#include"bmp.h"#include
using namespace std;int main(){ char* fileName = "qianxun.bmp"; Bitmap* bmp = new Bitmap(); bmp->read(fileName); bmp->translation(10, 10); //bmp->zoom(2, 2, 'n');//'n','l','c';默认为'n'邻近插值缩放 //bmp->rotate(90); bmp->write("translation.bmp"); delete bmp; return 1;}

转载于:https://www.cnblogs.com/corfox/p/5415024.html

你可能感兴趣的文章
启动vsftpd失败
查看>>
yii2组件之下拉框带搜索功能(yii-select2)
查看>>
Java串口通信详解
查看>>
Newtonsoft 自定义输出内容
查看>>
HTML图片元素(标记)
查看>>
windows server 2008 域控安装
查看>>
编写高质量代码:改善Java程序的151个建议(第1章:JAVA开发中通用的方法和准则___建议6~10)...
查看>>
Oracle查看和修改连接数(进程/会话/并发等等)
查看>>
【SpringMVC学习06】SpringMVC中的数据校验
查看>>
Laravel错误与日志处理
查看>>
微信小程序开发教程第七章:微信小程序编辑名片页面开发
查看>>
Java并发编程:Java ConcurrentModificationException异常原因和解决方法
查看>>
浅谈iOS中MVVM的架构设计
查看>>
node.js 中模块的循环调用问题详解
查看>>
ActiveReports 报表应用教程 (6)---分组报表
查看>>
OLEDB操作Excel
查看>>
struts2的json-default和struts-default的区别
查看>>
java中<> 的用法
查看>>
IIS 下配置无后缀的URL ReWrite
查看>>
对Asp.net Mvc 和 jQuery UI使用者的一些忠告
查看>>