首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

OpenCV 圖像傾斜變換:水平/垂直 Skewing 算法實現

     編輯:關於C++

效果展示

傾斜變換將圖像沿水平或垂直方向進行剪切映射,產生平行四邊形視覺效果。

原圖 水平傾斜 垂直傾斜

數學原理

水平傾斜

固定 y,x 隨 y 線性位移:x' = x + (height - y) * tan(θ)。輸出寬度需擴展:new_width = width + height * tan(θ)。

垂直傾斜

固定 x,y 隨 x 線性位移:y' = y + x * tan(θ)。輸出高度擴展:new_height = height + width * tan(θ)。

核心代碼(垂直傾斜為例)

#define pi 3.1415926
int main() {
    Mat Img = imread("4.jpg");
    float theta = pi/6; // 30度
    int width = Img.cols, height = Img.rows;
    
    // 垂直傾斜:輸出圖像更高
    int new_height = height + width * tan(theta) + 1;
    int new_width = width;
    Mat Img_V(new_height, new_width, CV_8UC3, Scalar(0));
    
    for (int y = 0; y < new_height; ++y) {
        for (int x = 0; x < new_width; ++x) {
            // 反向映射:目標 (x,y) ← 源 (x, y - x*tanθ)
            float Dis = x * tan(theta);
            float new_y = y - Dis;
            float new_x = x;
            
            // 邊界檢查與雙線性插值
            if (new_y >= 0 && new_y < height-1 && new_x >= 0 && new_x < width-1) {
                int y1 = (int)new_y, x1 = (int)new_x;
                float p = new_x - x1, q = new_y - y1;
                for (int k = 0; k < 3; ++k) {
                    Img_V.at(y, x)[k] = 
                        (1-p)*(1-q)*Img.at(y1, x1)[k] +
                        p*(1-q)*Img.at(y1, x1+1)[k] +
                        (1-p)*q*Img.at(y1+1, x1)[k] +
                        p*q*Img.at(y1+1, x1+1)[k];
                }
            }
        }
    }
    imshow("Vertical Skew", Img_V);
    imwrite("V.jpg", Img_V);
    waitKey();
    return 0;
}

關鍵技術點

  • 反向映射:遍歷目標圖像反查源圖像,保證無空洞。
  • 雙線性插值:四鄰域加權,消除最近鄰插值的塊效應。
  • 邊界處理:源座標超出範圍時不寫入(保持背景黑)或鏡像/複製邊緣。
  • 參數化角度:theta 可做成 Trackbar 實時調節。

通用仿射變換替代方案

OpenCV 內建 warpAffine 更高效:

Mat M = (Mat_(2,3) << 1, tan(theta), 0,  // 水平傾斜矩陣
                            0, 1, 0);
warpAffine(Img, dst, M, Size(new_width, new_height), INTER_LINEAR, BORDER_CONSTANT);

生產環境首選 warpAffine,手寫循環適合教學理解原理。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved