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

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

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

前言

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

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

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

1、4.5版本

4.5版本定義為,x軸順時(shí)針旋轉(zhuǎn)最先重合的邊為w,angle為x軸順時(shí)針旋轉(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)

中心點(diǎn)坐標(biāo):(201, 92),寬高: (20, 101),角度: 67。

配合旋轉(zhuǎn)函數(shù),可實(shí)現(xiàn)框的拉平。旋轉(zhuǎn)函數(shù)(逆時(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é)果:

 角度說(shuō)明:

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

 角度按逆時(shí)針旋轉(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)友測(cè)試4.1.*,4.2.*,4.3.*,4.4.*下minAreaRect函數(shù)的都一樣,就是網(wǎng)上常見(jiàn)的角度輸出為[-90~0]情況。但是實(shí)測(cè)python版本4系列的都為上述4.5版情況,可能是c++版本的不同吧。這里補(bǔ)充[-90~0]情況。

rect = cv2.minAreaRect(cnts[0])

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

寬、高和角度定義如下:角度為x軸沿逆時(shí)針旋轉(zhuǎn)遇到的第一個(gè)邊時(shí)的旋轉(zhuǎn)角度,因?yàn)槭悄鏁r(shí)針旋轉(zhuǎn)所以角度為0~-90度。約定:遇到的第一個(gè)邊為寬、另一個(gè)邊為高。

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

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

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

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

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

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

順時(shí)針為正,逆時(shí)針為負(fù)

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

參數(shù)詳解:

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

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

double scale:圖像縮放因子

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

minAreaRect():以X軸正方向?yàn)槠瘘c(diǎn),順時(shí)針為正,逆時(shí)針為負(fù)

getRotationMatrix2D():以X軸正方向?yàn)槠瘘c(diǎn),順時(shí)針為負(fù),逆時(shí)針為正

下面是一個(gè)例子:

#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)-----------------
	//計(jì)算偏轉(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軸正方形為起點(diǎn),順時(shí)針為正,逆時(shí)針為負(fù)
		degree = minrect.angle;
		
        //此處目的是為了讓目標(biāo)圖像旋轉(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軸正方形為起點(diǎn),順時(shí)針為負(fù),逆時(shí)針為正
	Mat rotimage;
	warpAffine(image, rotimage, rot, image.size());
	namedWindow("rotation", 0);
	resizeWindow("rotation", 800, 600);
	imshow("rotation", rotimage);
}

效果圖:

總結(jié)

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

相關(guān)文章

最新評(píng)論