본문 바로가기
프로젝트 모음/임베디드 Humanoid Project

[openCV] linetracer 중앙정렬

by 하람 Haram 2022. 11. 9.
728x90

기존 코드 : 컨투어 이용

############## 라인 트레이싱_중앙 정렬(제어보드로부터 Line_detect 수신 -> 첫번째) ##############
def make_middle_flag(cap, mid_yellow1,mid_yellow2,center_sensitive,mid_sensitive) -> 3:
    W_View_size = 640
    H_View_size = int(W_View_size / 1.333)
    right_flag = 320+center_sensitive
    left_flag = 320-center_sensitive
    ################[Can't,  Left,  Center,  Right]#########################
    lst_sensitive = [0,      0,     0,       0]
    past = 0
    sensitive = mid_sensitive

    while(True):
        _, src = cap.read() #영상파일 읽어드리기
        src = cv2.resize(src, (W_View_size, H_View_size)) #가져올 파일, ()이미지크기

        hsv = cv2.cvtColor(src, cv2.COLOR_BGR2HSV)

        yellow1 = mid_yellow1
        yellow2 = mid_yellow2
        mask_yellow = cv2.inRange(hsv, yellow1, yellow2)  # 노랑최소최대값을 이용해서 maskyellow값지정
        res_yellow = cv2.bitwise_and(src, src, mask=mask_yellow)  # 노랑색만 추출하기

        k = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
        dst = cv2.dilate(res_yellow, k)
        imgray = cv2.cvtColor(dst, cv2.COLOR_BGR2GRAY)
        cam = cv2.GaussianBlur(imgray, (3, 3), 0)  # 가우시안 블러
        _, cam_binary = cv2.threshold(cam, 127, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)  # 이진화
        contours, _ = cv2.findContours(cam_binary, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)  # 컨투어


        while (sensitive not in lst_sensitive):
            if len(contours) == 0:
                if past == 0: #연속된다면
                    lst_sensitive[0] += 1
                else: #연속이 아니라면
                    lst_sensitive = [0,   0,     0,    0]#초기화시켜주고
                    past = 0 #past를 바꿔주고
                    lst_sensitive[0] += 1
            else:
                contr = contours[0]
                x, y, w, h = cv2.boundingRect(contr)  # 최소한의 사각형 그려주는 함수
                cv2.rectangle(src, (x, y), (x + w, y + h), (0, 255, 0), 3)
                mid_x = x + (w/2)
                
                #Center => 2
                if mid_x > left_flag and mid_x < right_flag: 
                    if past == 2: #연속된다면
                        lst_sensitive[2] += 1
                    else: #past = 1,2 연속이 아니였다면
                        lst_sensitive = [0,   0,     0,    0]#초기화시켜주고
                        past = 2 #past를 바꿔주고
                        lst_sensitive[2] += 1
                        
                #Right
                elif mid_x >= right_flag:
                    if past == 3: #연속된다면
                        lst_sensitive[3] += 1
                    else:
                        lst_sensitive = [0,   0,     0,    0]#초기화시켜주고
                        past = 3
                        lst_sensitive[3] += 1
                #Left
                else:
                    if past == 1: #연속된다면
                        lst_sensitive[1] += 1
                    else:
                        lst_sensitive = [0,   0,     0,    0]
                        past = 1
                        lst_sensitive[1] += 1
                print(lst_sensitive)
        flag = lst_sensitive.index(sensitive)
        ################[Can't,  Left,  Center,  Right]#########################
        if flag == 0:
            print("Can't detect Yellow !!")
            flag =Line_no
        

        elif flag == 1:
            print("It's Left")
            flag = Line_left
        
        elif flag == 2:
            print("Robot on Center")
            flag = Line_mid

        else: #3
            print("It's Right")
            flag = Line_right
        
        

        #in robot
        # x: 30 왼: 32 중앙 31 오른쪽 33
        print(flag)
        ######################contest#######################
        return flag
        #####################################################

        cv.imshow("Original", src) #원본 화면
        #cv.imshow('Extract Yellow',res_yellow) #추출화면
        sleep(0.08)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

    cap.release()
    cv2.destroyAllWindows()  
''' x: Line_no(30) /  왼: Line_left(32) / 중앙 Line_mid(31) 오른쪽 Line_right(33) '''

무분별한 라인 검출이 원인

 

허프라인을 이용할 수도 있다는 점 고려하면서 진행하자

 

728x90