1. 程式人生 > >判斷兩個矩形是否有重疊

判斷兩個矩形是否有重疊

今天筆試遇到這個題目,原來是影象中的問題:判斷影象中檢測到的兩個人臉框矩形是否有重疊部分,並計算重疊大小,從而確認是否為同一個人臉。

直接判斷的話,情況有點多,比如:
在這裡插入圖片描述
這樣程式碼就比較繁瑣了。
如果是先考慮沒有重疊呢?
在這裡插入圖片描述
如上圖所示,沒有重疊的話,可以分為四種情況,假設紅色矩形為A,綠色矩形為B,那麼B可以分別在A的上、下、左、右四種情況。

設A的左上角座標為p1,右下角座標為p2,B的左上角座標為p3,右下角座標為p4,假設邊重疊不算重疊。
當B在A的上方時:p1.yp4.yp_1.y \leq p_4.y
當B在A的下方時:p3.yp2.yp_3.y \leq p_2.y


當B在A的左方時:p1.xp4.xp_1.x \geq p_4.x
當B在A的右方時:p2.xp3.xp_2.x \leq p_3.x

合起來就是:(p1.yp4.y)(p3.yp2.y)(p1.xp4.x)(p2.xp3.x)(p_1.y \leq p_4.y)\cup (p_3.y \leq p_2.y)\cup(p_1.x \geq p_4.x)\cup(p_2.x \leq p_3.x)

上式取反就是有重疊的情況:(

p1.y>p4.y)(p3.y>p2.y)(p1.x<p4.x)(p2.x>p3.x)(p_1.y >p_4.y)\cap (p_3.y > p_2.y)\cap(p_1.x < p_4.x)\cap(p_2.x > p_3.x)

class CPoint:
    def __init__(self,x,y):
        self.x=
x self.y=y class Rect: def __init__(self,p_left_top,p_right_bottom): self.p_left_top=p_left_top self.p_right_bottom=p_right_bottom def isOverlap(self,rect): if self.p_left_top.x<rect.p_right_bottom.x and self.p_right_bottom.x>rect.p_left_top.x and rect.p_left_top.y>self.p_right_bottom.y and self.p_left_top.y>rect.p_right_bottom.y: return True else: return False
import point
if __name__ == "__main__":
    rec1 = point.Rect(point.CPoint(2,10),point.CPoint(8,2))
    rec2 = point.Rect(point.CPoint(5, 1.5), point.CPoint(10, 1))
    print(rec1.isOverlap(rec2))

輸出False

方法二:求重疊區域

class CPoint:
    def __init__(self,x,y):
        self.x=x
        self.y=y
class Rect:
    def __init__(self,p_left_top,p_right_bottom):
        #p_left_top:左上角頂點
        #p_right_bottom右下角頂點
        self.p_left_top=p_left_top
        self.p_right_bottom=p_right_bottom

    def isOverlap(self,rect):
        #是否有重疊,如果有重疊,返回重疊面積,否則返回0
        cv_point_top=CPoint(max(self.p_left_top.x,rect.p_left_top.x),min(self.p_left_top.y,rect.p_left_top.y))#重疊區域的左上角頂點
        cv_point_bottom=CPoint(min(self.p_right_bottom.x,rect.p_right_bottom.x),max(self.p_right_bottom.y,rect.p_right_bottom.y))#重疊區域的右下角頂點
        if cv_point_bottom.x>cv_point_top.x and cv_point_bottom.y<cv_point_top.y:
            join_area=(cv_point_bottom.x-cv_point_top.x)*(cv_point_top.y-cv_point_bottom.y)#重疊區域面積
            self.area=(self.p_right_bottom.x-self.p_left_top.x)*(self.p_left_top.y-self.p_right_bottom.y)#矩形A的面積
            rect.area=(rect.p_right_bottom.x-rect.p_left_top.x)*(rect.p_left_top.y-rect.p_right_bottom.y)#矩形B的面積
            return join_area/(self.area+rect.area-join_area)
        else:
            return 0
import point
if __name__ == "__main__":
    rec1 = point.Rect(point.CPoint(2,10),point.CPoint(8,2))
    rec2 = point.Rect(point.CPoint(5, 7), point.CPoint(10, 1))
    print(rec1.isOverlap(rec2))

輸出:0.23809523809523808