[原始碼] C / C++ 如何旋轉圖片
https://charlottehong.blogspot.tw/2017/11/bilinear.html
旋轉公式
公式1 - for跑原圖映射到新圖
x' = x * cos(theta) - sin(theta) * y
y' = x * sin(theta) + cos(theta) * y
公式2 - for跑新圖映射回原圖
float r_rot = (j)*sin_t + (i)*cos_t; // 原圖X座標
float c_rot = (j)*cos_t - (i)*sin_t; // 原圖Y座標
// 預算
float cos_t = cosf(sita*(float)(M_PI/180));
float sin_t = sinf(sita*(float)(M_PI/180));
原點在哪裡
範例代碼
(懶懶的~還沒補上又真的有需要然後看不懂可以直接留言問吧~我會看到的)
ImgRaw rotateImg(const ImgRaw& sou, size_t x, size_t y, float radius, float sita) {
ImgRaw test = sou;
//test.at2d(x, y) = 1;
Draw::draw_arrow(test, y, x, radius, sita, 1);
test.bmp("rotate_test.bmp");
// 新圖長寬半徑
float maxRadius = radius;
int rotH = floor(maxRadius);
int rotW = floor(maxRadius);
ImgRaw rotate(rotW*2, rotH*2, 8);
// 預算
sita *= -1; // 把新圖轉回0度
float cos_t = cosf(sita*(float)(M_PI/180));
float sin_t = sinf(sita*(float)(M_PI/180));
// 跑新圖
for (int j = -rotH; j < rotH; j++) {
for (int i = -rotW; i < rotW; i++) {
// 輸入新圖座標返回舊圖座標(已0, 0為圓心旋轉)
float r_rot = (j)*sin_t + (i)*cos_t; // 原圖X座標
float c_rot = (j)*cos_t - (i)*sin_t; // 原圖Y座標
// 矯正回指定位置
float rbin = r_rot + x;
float cbin = c_rot + y;
// 去除原圖外的點
if (cbin < sou.height - 1 and cbin > 0) {
if (rbin < sou.width - 1 and rbin > 0) {
// 雙線姓插補
rotate.at2d(j+rotH, i+rotW) = test.atBilinear(cbin, rbin);
}
}
}
}
return rotate;
}
- 一維陣列
- 長寬
- 位元數(彩圖灰圖)
- 一些方法
線性插補建議寫成一個讀取的,這樣規劃結構還不錯用 atBilinear(y, x) 要是你輸入的點不正好在點上,比如說 (0.5, 0.5) 就算出這個位置的插補值回傳。
- 點(y, x)
- 角度
- 半徑
- 畫出點與半徑的箭頭
- 把點與角度轉正向右
- 擷取點為中心半徑的距離
其實就是SIFT算法的一小部分,轉正主角度時用到到的