欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

OpenCV實(shí)現(xiàn)繞圖片中任意角度旋轉(zhuǎn)任意角度

 更新時(shí)間:2022年09月29日 08:30:38   作者:萬(wàn)丈高樓平地起  
這篇文章主要為大家詳細(xì)介紹了在圖片不被裁剪時(shí),opencv如何實(shí)現(xiàn)繞圖片中任意點(diǎn)旋轉(zhuǎn)任意角度,文中的示例代碼講解詳細(xì),需要的可以參考一下

最近在做項(xiàng)目需要把把圖片繞圖片中任意點(diǎn)旋轉(zhuǎn)任意角度,考慮到自己旋轉(zhuǎn)需要編寫(xiě)插值算法,所以想到了用opencv,但是網(wǎng)上都是圍繞圖片中點(diǎn)旋轉(zhuǎn)任意角度的,都是向下面這樣寫(xiě)的:

繞圖片中心旋轉(zhuǎn)圖片不裁剪

#include"opencv.hpp"
#include<iostream>
using namespace std;
using namespace cv;
int main() {
	Mat src = imread("timg.jpg");
	Mat des,m;
	Point2f center = Point(src.cols / 2, src.rows / 2);
	double angle = 50,scale=0.5;
	int w = src.cols, h = src.rows;
	int bound_w = (h * fabs(sin(angle * CV_PI / 180)) + w * fabs(cos(angle * CV_PI / 180))) * scale;
	int bound_h = (h * fabs(cos(angle * CV_PI / 180)) + w * fabs(sin(angle * CV_PI / 180))) * scale;
	m = getRotationMatrix2D(center, angle, scale);
	m.at<double>(0, 2) += (bound_w - src.cols) / 2;
	m.at<double>(1, 2) += (bound_h - src.rows) / 2;
	
	warpAffine(src,des,m,Size2i(bound_h,bound_w));
	imshow("image",des);
	waitKey();
	return 0;

旋轉(zhuǎn)之后的效果: 

但是遇到繞任意點(diǎn)旋轉(zhuǎn)時(shí),會(huì)產(chǎn)生問(wèn)題,用這種方式還是會(huì)存在裁剪,如果要理解繞任意點(diǎn)旋轉(zhuǎn),需要先理解函數(shù)getRotationMatrix2D,這個(gè)函數(shù)處理過(guò)程如下面矩陣表示所示:

具體實(shí)現(xiàn)代碼如下:

    Mat src = imread("/home/sss/1111.jpg", IMREAD_GRAYSCALE);
    Mat des, m;
//旋轉(zhuǎn)的任意角度
    double angle = 45;
    int w = src.cols, h = src.rows;
    Point2f rorate_center;
//旋轉(zhuǎn)的任意中心
    rorate_center.x = w;
    rorate_center.y = h;
//重新計(jì)算旋轉(zhuǎn)后的寬和高
    int bound_w = ceil(h * fabs(sin(angle * CV_PI / 180.0)) + w * fabs(cos(angle * CV_PI / 180.0)));
    int bound_h = ceil(h * fabs(cos(angle * CV_PI / 180.0)) + w * fabs(sin(angle * CV_PI / 180.0)));
    m = getRotationMatrix2D(rorate_center, angle, 1.0);

//通過(guò)eigen計(jì)算旋轉(zhuǎn)矩陣
    Eigen::Matrix3d T1;
    T1 << 1, 0, -rorate_center.x,
            0, 1, -rorate_center.y,
            0, 0, 1;
    Eigen::Matrix3d T2;
    T2 <<   1, 0, rorate_center.x,
            0, 1, rorate_center.y,
            0, 0, 1;
    Eigen::Matrix3d rorate;
    rorate << cos(angle * CV_PI / 180.0), sin(angle * CV_PI / 180.0), 0,
            -sin(angle * CV_PI / 180.0), cos(angle * CV_PI / 180.0), 0,
            0, 0, 1;
    Eigen::Matrix3d T = T2 * rorate * T1;
//計(jì)算原來(lái)矩陣的四個(gè)頂點(diǎn)經(jīng)過(guò)變換后的頂點(diǎn)
    Eigen::Matrix<double,3, 1> left_top_p, right_top_p, right_bottom_p, left_botoom_p;
    left_top_p << 0, 0, 1;
    right_top_p << w, 0, 1;
    right_bottom_p << w, h, 1;
    left_botoom_p << 0, h , 1;
    left_top_p = T * left_top_p;
    right_top_p = T * right_top_p;
    right_bottom_p = T * right_bottom_p;
    left_botoom_p = T * left_botoom_p;

//找到經(jīng)過(guò)變換過(guò)定位的最大最小值
    double min_x = 10000, min_y = 10000;
    //min_x
    if(left_top_p[0] < min_x){
        min_x = left_top_p[0];
    }
    if(right_top_p[0] < min_x){
        min_x = right_top_p[0];
    }
    if(right_bottom_p[0] < min_x)
    {
        min_x = right_bottom_p[0];
    }
    if(left_botoom_p[0] < min_x){
        min_x = left_botoom_p[0];
    }

    //min_y
    if(left_top_p[1] < min_y){
        min_y = left_top_p[1];
    }
    if(right_top_p[1] < min_y){
        min_y = right_top_p[1];
    }
    if(right_bottom_p[1] < min_y)
    {
        min_y = right_bottom_p[1];
    }
    if(left_botoom_p[1] < min_y){
        min_y = left_botoom_p[1];
    }

    double max_x = -1000, max_y = -1000;
    //max_x
    if(left_top_p[0] > max_x){
        max_x = left_top_p[0];
    }
    if(right_top_p[0] > max_x){
        max_x = right_top_p[0];
    }
    if(right_bottom_p[0] > max_x)
    {
        max_x = right_bottom_p[0];
    }
    if(left_botoom_p[0] > max_x){
        max_x = left_botoom_p[0];
    }

    //max_y
    if(left_top_p[1] > max_y){
        max_y = left_top_p[1];
    }
    if(right_top_p[1] > max_y){
        max_y = right_top_p[1];
    }
    if(right_bottom_p[1] > max_y)
    {
        max_y = right_bottom_p[1];
    }
    if(left_botoom_p[1] > max_y){
        max_y = left_botoom_p[1];
    }

    //將偏置添加到矩陣中
    m.at<double>(0, 2) += -min_x;
    m.at<double>(1, 2) += -min_y;

//變換,最后不會(huì)存在裁剪
    warpAffine(src, des , m , Size2i(bound_w , bound_h),
               INTER_LINEAR, 0, Scalar(100, 100, 100));
    imwrite("/home/sss/222.jpg", des);
    return 0;

經(jīng)過(guò)變換過(guò)的圖片不會(huì)存在裁剪:

到此這篇關(guān)于OpenCV實(shí)現(xiàn)繞圖片中任意角度旋轉(zhuǎn)任意角度的文章就介紹到這了,更多相關(guān)OpenCV圖片旋轉(zhuǎn)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 教你用C語(yǔ)言實(shí)現(xiàn)三子棋

    教你用C語(yǔ)言實(shí)現(xiàn)三子棋

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單三子棋程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • 關(guān)于C++中的static關(guān)鍵字的總結(jié)

    關(guān)于C++中的static關(guān)鍵字的總結(jié)

    C++的static有兩種用法:面向過(guò)程程序設(shè)計(jì)中的static和面向?qū)ο蟪绦蛟O(shè)計(jì)中的static。前者應(yīng)用于普通變量和函數(shù),不涉及類(lèi);后者主要說(shuō)明static在類(lèi)中的作用
    2013-09-09
  • C++ map詳解

    C++ map詳解

    下面小編就為大家?guī)?lái)一篇淺談c++中的map。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2021-10-10
  • C++中的STL中map用法詳解(零基礎(chǔ)入門(mén))

    C++中的STL中map用法詳解(零基礎(chǔ)入門(mén))

    map在編程中是經(jīng)常使用的一個(gè)容器,本文來(lái)講解一下STL中的map,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • VSCode插件開(kāi)發(fā)全攻略之打包、發(fā)布、升級(jí)的詳細(xì)教程

    VSCode插件開(kāi)發(fā)全攻略之打包、發(fā)布、升級(jí)的詳細(xì)教程

    這篇文章主要介紹了VSCode插件開(kāi)發(fā)全攻略之打包、發(fā)布、升級(jí)的教程,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-05-05
  • C++實(shí)現(xiàn)動(dòng)態(tài)煙花代碼

    C++實(shí)現(xiàn)動(dòng)態(tài)煙花代碼

    這篇文章主要介紹了利用C++實(shí)現(xiàn)的放煙花程序,用到了EGE圖形庫(kù),文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)C++有一定幫助,需要的可以參考一下
    2023-01-01
  • Qt事件過(guò)濾實(shí)現(xiàn)點(diǎn)擊圖片的放大和縮小

    Qt事件過(guò)濾實(shí)現(xiàn)點(diǎn)擊圖片的放大和縮小

    這篇文章主要為大家詳細(xì)介紹了Qt事件過(guò)濾實(shí)現(xiàn)點(diǎn)擊圖片的放大和縮小,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • C++實(shí)現(xiàn)讀取圖片長(zhǎng)度和寬度

    C++實(shí)現(xiàn)讀取圖片長(zhǎng)度和寬度

    這篇文章主要介紹了C++實(shí)現(xiàn)讀取圖片長(zhǎng)度和寬度,本文直接給出實(shí)現(xiàn)代碼,需要的朋友可以參考下
    2015-04-04
  • c++中引用作為形參的使用方法以及作用

    c++中引用作為形參的使用方法以及作用

    這篇文章主要給大家介紹了關(guān)于c++中引用作為形參的使用方法以及作用的相關(guān)資料,引用是地址傳值,作為引用的形參數(shù)值被修改的同時(shí),也修改了對(duì)應(yīng)實(shí)參的值,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-11-11
  • VC程序設(shè)計(jì)小技巧20例

    VC程序設(shè)計(jì)小技巧20例

    這篇文章主要介紹了VC程序設(shè)計(jì)小技巧20例,需要的朋友可以參考下
    2014-07-07

最新評(píng)論