91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么在OpenCV中利用C++ 實現一個圖片旋轉效果

發布時間:2020-12-15 14:43:18 來源:億速云 閱讀:861 作者:Leah 欄目:開發技術

本篇文章為大家展示了怎么在OpenCV中利用C++ 實現一個圖片旋轉效果,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。

圖片旋轉,本質上是對旋轉后的圖片中每個像素點計算在原圖的位置。然后照搬過來就好。

圖形圖像課上一般會介紹旋轉變換矩陣,其中 t 為需要旋轉的角度,[x'; y']是變換后坐標(其中分號表示上下關系):

怎么在OpenCV中利用C++ 實現一個圖片旋轉效果

即表示為:[x'; y'] = [cos(t) sin(t); -sin(t) cos(t)][x; y]

因為我個人興趣愛好(放P就是老師逼的。。。),不允許使用 OpenCV 封裝好的旋轉函數。只能自己實現,我開始的想法是:先求變換矩陣逆矩陣,然后將一張全黑圖中每個點一一對應插值到原圖中。

結果發現轉換后圖片全黑了……

后來發現原點設置不對。用OpenCV中的 Mat格式存儲(或二維數組)的圖片, 原點在左上角 。但是想要實現的 旋轉原點在圖片中心 。

同時, Mat格式存儲(或二維數組)的 坐標系中 y軸正方向向下 。這樣人類視覺上的順時針旋轉,在二維數組的坐標系中是逆時針旋轉。

最重要的一點,也是二維數組操作中極易忽略的一點: 數組操作的是 數組下標 ,不是坐標系(數組的行數 rows 是矩形的寬 width ,列數 cols 是矩形的長 length ) 。比如坐標系(此時為了更貼近數組布局,我們 假設 y 軸坐標系是向下的 )中,矩形頂點是:

怎么在OpenCV中利用C++ 實現一個圖片旋轉效果

但是在數組中,因為是行優先,所以四個點的下標取值為:

怎么在OpenCV中利用C++ 實現一個圖片旋轉效果

有沒有發現,兩種坐標是相反的!

總結下來,我們的圖片旋轉需要注意以下幾點:

  1. 變換后圖片中的每個像素點(i; j),需要平移到相對旋轉中心的新坐標,即(i - Mat.rows/2; j - Mat.cols/2)。計算完成之后,需要再次 還原 到相對左上角原點的舊坐標;

  2. 本來需要 變換后圖片 乘以 原圖 變換矩陣的 逆矩陣 對應到原圖中坐標。但是因為y軸方向向下,所以 變換后圖片 乘以 原圖 變換矩陣(無需逆矩陣) 即可對應到原圖中坐標(順時針旋轉50度,還原操作是逆時針旋轉50度);

  3. 矩陣下標與原圖變換矩陣相乘之前,需要將矩陣 下標兩值互換 。相乘之后,需要 再次互換下標值 還原成矩陣下標。

因此對于一個經過旋轉 t 度之后 數組下標 為[m‘, n']的像素值,還原成原圖中的 數組下標 [m; n]計算為:

[cos(t) -sin(t); sin(t) cos(t)] ([m'; n'] - [Mat.rows/2; Mat.cols/2]) = [m; n] -  [Mat.rows/2; Mat.cols/2]

源代碼附上:

Mat nearestNeighRotate(cv::Mat img, float angle)
{
	int len = (int)(sqrtf(pow(img.rows, 2) + pow(img.cols, 2)) + 0.5);

	Mat retMat = Mat::zeros(len, len, CV_8UC3);
	float anglePI = angle * CV_PI / 180;
	int xSm, ySm;

	for(int i = 0; i < retMat.rows; i++)
		for(int j = 0; j < retMat.cols; j++)
		{
			xSm = (int)((i-retMat.rows/2)*cos(anglePI) - (j-retMat.cols/2)*sin(anglePI) + 0.5);
			ySm = (int)((i-retMat.rows/2)*sin(anglePI) + (j-retMat.cols/2)*cos(anglePI) + 0.5);
			xSm += img.rows / 2;
			ySm += img.cols / 2;

			if(xSm >= img.rows || ySm >= img.cols || xSm <= 0 || ySm <= 0){
				retMat.at<Vec3b>(i, j) = Vec3b(0, 0);
			}
			else{
				retMat.at<Vec3b>(i, j) = img.at<Vec3b>(xSm, ySm);
			}
		}

	return retMat;
}

好,我們來測試看看:

int main() 
{ 
	Mat img = imread("../HelloWorld.png");
	retImg = nearestNeighRotate(img, -20.f);
	namedWindow("nearNeigh", CV_WINDOW_AUTOSIZE);
	imshow("nearNeigh", retImg);

	waitKey(); 
	cvDestroyAllWindows();
	return 0; 
}

上述內容就是怎么在OpenCV中利用C++ 實現一個圖片旋轉效果,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

辉县市| 尚义县| 辉南县| 上蔡县| 湘阴县| 雷山县| 黄冈市| 区。| 琼结县| 天峨县| 潮州市| 福州市| 北票市| 思茅市| 海林市| 北辰区| 龙泉市| 牟定县| 天镇县| 湖北省| 濮阳县| 神木县| 顺义区| 西充县| 墨脱县| 友谊县| 河曲县| 大渡口区| 洛南县| 来安县| 天长市| 胶南市| 清徐县| 巩留县| 清苑县| 博客| 永靖县| 海南省| 北宁市| 榆社县| 六枝特区|