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

opencv中cv2.minAreaRect函數(shù)輸出角度問題詳解

 更新時間:2022年11月18日 11:46:32   作者:alex1801  
minAreaRect返回的數(shù)據(jù)包括了矩形的中心點,寬、高,和旋轉(zhuǎn)角度,下面這篇文章主要給大家介紹了關于opencv中cv2.minAreaRect函數(shù)輸出角度問題的相關資料,需要的朋友可以參考下

前言

網(wǎng)上很多例子都說cv2.minAreaRect函數(shù)的輸出的角度范圍在[-90,0],但是實測輸出范圍在[0,90]。再進行調(diào)研,確定為opencv4.5版本升級改動引起。

cv2.minAreaRect輸入:四邊形的四個點(不要求順序)。

輸出:最小外接矩形的中心點坐標x,y,寬高w,h,角度anlge,輸出形式為元組((x,y),(w,h),anlge),順序格式不變。

1、4.5版本

4.5版本定義為,x軸順時針旋轉(zhuǎn)最先重合的邊為w,angle為x軸順時針旋轉(zhuǎn)的角度,angle取值為(0,90]。

cnts, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
rect = cv2.minAreaRect(cnts[0])
box = np.int0(cv2.boxPoints(rect))
print(rect)

輸出結(jié)果:((201.25, 92.10), (20.93, 101.94), 67.47)

中心點坐標:(201, 92),寬高: (20, 101),角度: 67。

配合旋轉(zhuǎn)函數(shù),可實現(xiàn)框的拉平。旋轉(zhuǎn)函數(shù)(逆時針旋轉(zhuǎn)):

import cv2
import numpy as np
 
def rotate(img, angle, center=None, scale=1.0, fill=0, interpolation=cv2.INTER_LINEAR, expand=True):
    if center is not None and expand:
        raise ValueError('`auto_bound` conflicts with `center`')
 
    h, w = img.shape[:2]
    if center is None:
        center = ((w - 1) * 0.5, (h - 1) * 0.5)
    assert isinstance(center, tuple)
 
    matrix = cv2.getRotationMatrix2D(center, angle, scale)
    if expand:
        cos = np.abs(matrix[0, 0])
        sin = np.abs(matrix[0, 1])
        new_w = h * sin + w * cos
        new_h = h * cos + w * sin
        matrix[0, 2] += (new_w - w) * 0.5
        matrix[1, 2] += (new_h - h) * 0.5
        w = int(np.round(new_w))
        h = int(np.round(new_h))
    rotated = cv2.warpAffine(
        img,
        matrix, (w, h),
        flags=interpolation,
        borderValue=fill)
    return rotated

執(zhí)行旋轉(zhuǎn):

rotate(img, -23, center=(201, 92), expand=False)

結(jié)果:

 角度說明:

角度為x軸順時針旋轉(zhuǎn),第一次接觸到矩形邊界時的值,范圍:0~90°,第一次接觸的邊界為寬,區(qū)分方向可以使用寬、高的值來確定。

 角度按逆時針旋轉(zhuǎn)方式調(diào)整為:

if rect[1][0] > rect[1][1]: # w > h 
    angle = int(rect[2]) 
else: 
    angle = -(90 - int(rect[2]))

2、4.5之前版本

有網(wǎng)友測試4.1.*,4.2.*,4.3.*,4.4.*下minAreaRect函數(shù)的都一樣,就是網(wǎng)上常見的角度輸出為[-90~0]情況。但是實測python版本4系列的都為上述4.5版情況,可能是c++版本的不同吧。這里補充[-90~0]情況。

rect = cv2.minAreaRect(cnts[0])

rect[0]返回最小外接矩形的中心點,rect[1]為最小外接矩形的寬、高。rect[2]為旋轉(zhuǎn)角度。

寬、高和角度定義如下:角度為x軸沿逆時針旋轉(zhuǎn)遇到的第一個邊時的旋轉(zhuǎn)角度,因為是逆時針旋轉(zhuǎn)所以角度為0~-90度。約定:遇到的第一個邊為寬、另一個邊為高。

補充:opencv ---minAreaRect()計算偏轉(zhuǎn)角度并糾正

  • 此次試驗的目的是計算目標圖像偏轉(zhuǎn)的角度,在不改變圖像尺寸下糾正
  • 這里主要用到minAreaRect()函數(shù)和getRotationMatrix2D()函數(shù)
  • 先簡單的介紹下minAreaRect()函數(shù),本人在這里踩了一些坑,在這里說明一下,如有不妥的地方,大家盡管指正。

函數(shù)為minAreaRect(InputArray points) ,InputArray points是所要求最小外接矩形的點集,這個點集不定個數(shù)。

這個矩形是可以有偏轉(zhuǎn)角度的,可以與圖像的邊界不平行。

調(diào)用形式:RotatedRect minAreaRect(InputArray points)

  • 角度計算規(guī)則:以左上角為原點,X軸逆時針旋轉(zhuǎn),所得到的第一個角度即為旋轉(zhuǎn)角度,第一條邊為最小外接矩形的寬。角度范圍[-90,0],當最小外接矩形平行(或垂直)X軸時角度為-90。(跟目標圖像的長寬沒關系)

順時針為正,逆時針為負

  • 函數(shù)getRotationMatrix2D(Point2f center, double angle, double scale)

參數(shù)詳解:

Point2f center:表示旋轉(zhuǎn)的中心點

double angle:表示旋轉(zhuǎn)的角度  //這里的角度順時針為負,逆時針為正

double scale:圖像縮放因子

  • 踩坑的地方主要在角度分不清,我總結(jié)了一下:

minAreaRect():以X軸正方向為起點,順時針為正,逆時針為負

getRotationMatrix2D():以X軸正方向為起點,順時針為負,逆時針為正

下面是一個例子:

#include <iostream>
#include <string>
#include <math.h>
#include <vector>
#include <io.h>
#include <fstream>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
 
using namespace cv;
using namespace std;
 
int main()
{  
	Mat image = imread("a11.jpg");  
	Mat gaussianimage,grayimage, cannyimage, thresholdimage;
 
//---------------------旋轉(zhuǎn)-----------------
	//計算偏轉(zhuǎn)角度
	GaussianBlur(image, gaussianimage, Size(5, 5), 3, 3);//盡可能多的去除雜質(zhì)
	Canny(gaussianimage, cannyimage, 50, 150, 3);
	cvtColor(cannyimage, grayimage, CV_GRAY2BGR);
	vector<vector<Point>>vec_point;
	vector<Vec4i>hireachy;
	findContours(cannyimage, vec_point, hireachy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
 
	double degree = 0;
	for (size_t i = 0; i < vec_point.size(); i++)
	{
		RotatedRect minrect = minAreaRect(vec_point[i]);//minAreaRect():以X軸正方形為起點,順時針為正,逆時針為負
		degree = minrect.angle;
		
        //此處目的是為了讓目標圖像旋轉(zhuǎn)到水平位置
		if (degree > -90 && degree <= -45)
		{
			degree += 90;
		}
		else if (degree >-45 && degree < 0)
		{
			degree;
		}
		else
		{
			degree = 0;
		}		
		cout <<"degree:" << degree << endl;
	}	
 
	//旋轉(zhuǎn)糾正
	Point center = Point(image.cols / 2, image.rows / 2);
	double angle = degree;
	double scale = 1;
	Mat rot(2, 3, CV_32FC1);
	rot = getRotationMatrix2D(center, angle, scale);//getRotationMatrix2D():以X軸正方形為起點,順時針為負,逆時針為正
	Mat rotimage;
	warpAffine(image, rotimage, rot, image.size());
	namedWindow("rotation", 0);
	resizeWindow("rotation", 800, 600);
	imshow("rotation", rotimage);
}

效果圖:

總結(jié)

到此這篇關于opencv中cv2.minAreaRect函數(shù)輸出角度問題的文章就介紹到這了,更多相關opencv cv2.minAreaRect函數(shù)輸出角度內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:

相關文章

最新評論