OpenCV查找此图像的轮廓以进行裁剪和旋转

时间:2020-06-30 13:32:48

标签: opencv opencv-contour

我正在尝试检测此图像的轮廓,以便在openCV中对其进行裁剪。

我想出了有效的代码,但是,如果图像上有一些轻微的背景,它将失败。

图像处理:

enter image description here

检测边界(蓝点):

enter image description here

裁剪/旋转:

enter image description here

但是,对于像这样的图像和一些背景光,它将不起作用:

enter image description here

预处理:

enter image description here

边界检测:

enter image description here

def preProcessing(img):
    imgGray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

    adaptive_thresold1 = 31
    adaptive_thresold2 = 7

    blur = cv2.blur(imgGray, (3, 3))
    thresh = cv2.adaptiveThreshold(blur,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,adaptive_thresold1,adaptive_thresold2)

    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
    close = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel, iterations=2)

    stackedImages = hp.stackImages(0.1,([img,thresh, close],[img,thresh, close]))
    cv2.imshow("WorkFlow", stackedImages)
    cv2.waitKey(0) 
    return thresh


def getContours(img):
    biggest = np.array([])
    maxArea = 0
    img = cv2.bitwise_not(img)
    contours,hierarchy = cv2.findContours(img,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
    
    for cnt in contours:
        area = cv2.contourArea(cnt)
        if area>5000:
            print (area)
            
            #cv2.drawContours(imgContour, cnt, -1, (255, 0, 0), 3)
            peri = cv2.arcLength(cnt,True)
            approx = cv2.approxPolyDP(cnt,0.02*peri,True)
            
            if area >maxArea and len(approx) == 4:
                biggest = approx
                maxArea = area
                print ("ok")
                
    print (biggest)
    out = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
    cv2.drawContours(out, biggest, -1, (255, 0, 0), 50)

    stackedImages = hp.stackImages(0.1,([img,out],[img,out]))
    cv2.imshow("WorkFlow", stackedImages)
    cv2.waitKey(0)

    return biggest

是否有任何建议使此代码更可靠?

1 个答案:

答案 0 :(得分:1)

请尝试使用Otsu's thresholding,而不是使用自适应阈值。

更改此行

Launching lib\lead.dart on Redmi Note 4 in debug mode...
Running Gradle task 'assembleDebug'...
√ Built build\app\outputs\flutter-apk\app-debug.apk.
Installing build\app\outputs\flutter-apk\app.apk...
Waiting for Redmi Note 4 to report its views...
D/SharedPreferencesImpl(26836): Time required to fsync /data/user/0/co.MayankKumar.micard/shared_prefs/com.google.android.gms.measurement.prefs.xml: [<1: 0, <2: 0, <4: 0, <8: 0, <16: 1, <32: 1, <64: 1, <128: 0, <256: 0, <512: 0, <1024: 1, <2048: 0, <4096: 0, <8192: 0, <16384: 0, >=16384: 0]
Debug service listening on ws://127.0.0.1:59088/uGAKr_NsdvA=/ws
Syncing files to device Redmi Note 4...
W/ankKumar.micar(26836): Accessing hidden method Landroid/view/accessibility/AccessibilityNodeInfo;->getSourceNodeId()J (light greylist, reflection)
W/ankKumar.micar(26836): Accessing hidden method Landroid/view/accessibility/AccessibilityRecord;->getSourceNodeId()J (light greylist, reflection)
W/ankKumar.micar(26836): Accessing hidden field Landroid/view/accessibility/AccessibilityNodeInfo;->mChildNodeIds:Landroid/util/LongArray; (light greylist, reflection)
W/ankKumar.micar(26836): Accessing hidden method Landroid/util/LongArray;->get(I)J (light greylist, reflection)
D/SharedPreferencesImpl(26836): Time required to fsync /data/user/0/co.MayankKumar.micard/shared_prefs/com.google.android.gms.measurement.prefs.xml: [<1: 0, <2: 0, <4: 0, <8: 0, <16: 1, <32: 1, <64: 1, <128: 0, <256: 0, <512: 1, <1024: 1, <2048: 0, <4096: 0, <8192: 0, <16384: 0, >=16384: 0]
I/OpenGLRenderer(26836): Initialized EGL, version 1.4
D/OpenGLRenderer(26836): Swap behavior 2
I/Choreographer(26836): Skipped 61 frames!  The application may be doing too much work on its main thread.
I/OpenGLRenderer(26836): Davey! duration=3545ms; Flags=1, IntendedVsync=645934273575483, Vsync=645935290242109, OldestInputEvent=9223372036854775807, NewestInputEvent=0, HandleInputStart=645935303833077, AnimationStart=645935303911567, PerformTraversalsStart=645935305227348, DrawStart=645935312171411, SyncQueued=645935314591776, SyncStart=645935314695005, IssueDrawCommandsStart=645935314944172, SwapBuffers=645937816483484, FrameCompleted=645937819231817, DequeueBufferDuration=2150000, QueueBufferDuration=513000, 
D/SharedPreferencesImpl(26836): Time required to fsync /data/user/0/co.MayankKumar.micard/shared_prefs/com.google.android.gms.appid.xml: [<1: 0, <2: 0, <4: 0, <8: 1, <16: 0, <32: 0, <64: 0, <128: 0, <256: 0, <512: 1, <1024: 0, <2048: 0, <4096: 0, <8192: 0, <16384: 0, >=16384: 0]
E/FirebaseInstanceId(26836): binding to the service failed.

在您的代码中--

thresh = cv2.adaptiveThreshold(blur,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,adaptive_thresold1,adaptive_thresold2)

这在图片中对我有用。