1

I know that this issue has other posts, but none of them helped me:

import cv2 as cv
import numpy as np

widthImg = 640
heightImg = 480

frameWidth = 640
frameHeight = 480
cap = cv.VideoCapture(2)
cap.set(3, widthImg)
cap.set(4, heightImg)
cap.set(10,150)


def preProcessing(img):
    imgGray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
    imgBlur = cv.GaussianBlur(imgGray,(5,5),1)
    imgCanny = cv.Canny(imgBlur,200,200)
    kernel = np.ones((5,5))
    imgDial = cv.dilate(imgCanny,kernel,iterations=2)
    imgThres = cv.erode(imgDial,kernel,iterations=1)
    return imgThres

def getContours(img):
    biggest = np.array([])
    maxArea = 0
    contours,hierarchy = cv.findContours(img,cv.RETR_EXTERNAL,cv.CHAIN_APPROX_NONE)
    for cnt in contours:
        area = cv.contourArea(cnt)
        if area>5000:
            #cv.drawContours(imgContour, cnt, -1, (255,0,0), 3)
            peri = cv.arcLength(cnt,True)
            approx = cv.approxPolyDP(cnt,0.02*peri,True)
            if area >maxArea and len(approx) == 4:
                biggest = approx
                maxArea = area
    cv.drawContours(imgContour, biggest, -1, (255, 0, 0), 20)
    return biggest

def getWarp(img,biggest):

    pts1 = np.array(biggest,np.float32)
    pts2 = np.array([[0, 0], [widthImg, 0], [0, heightImg], [widthImg, heightImg]],np.float32)
    matrix = cv.getPerspectiveTransform(pts1, pts2)
    imgOutput = cv.warpPerspective(img, matrix, (widthImg, heightImg))

    return imgOutput


while True:
    success, img = cap.read()
    img = cv.resize(img,(widthImg,heightImg))
    imgContour = img.copy()


    imgThres = preProcessing(img)
    biggest = getContours(imgThres)
    print(biggest)
    imgWarped = getWarp(img,biggest)


    cv.imshow("Result", imgWarped)
    if cv.waitKey(1) & 0xFF == ord('q'):
        break

So this is my code in Pycharm. I know that the problem came when I use 'biggest' at the 44 line (pts1 = np.array(biggest,np.float32) I know that if I write 4 two-dimensional points instead 'biggest' it will work. But in a video that i'm following, the programmer used 'biggest' without any problem. I know that it already said that 'biggest' has 4 points (in def getContours(img):). I don't know why is not working in my case and in others yes.

And this is the error message that I get:

Traceback (most recent call last):
  File "/home/nvidia/PycharmProjects/OpencvPython/Resources/Project2.py", line 61, in <module>
    imgWarped = getWarp(img,biggest)
  File "/home/nvidia/PycharmProjects/OpencvPython/Resources/Project2.py", line 46, in getWarp
    matrix = cv.getPerspectiveTransform(pts1, pts2)
cv2.error: OpenCV(4.5.1) /tmp/pip-req-build-q3gzfcr4/opencv/modules/imgproc/src/imgwarp.cpp:3392: error: (-215:Assertion failed) src.checkVector(2, CV_32F) == 4 && dst.checkVector(2, CV_32F) == 4 in function 'getPerspectiveTransform'

Sorry if this is a stupid issue but I'm new in python programming and I spend a couple of hours trying to solve it.

AntonP
  • 11
  • 2
  • If there are no contours with area over 5000, then `biggest` will be empty, and there's nothing in your code that would prevent it from calling `getPerspectiveTransform` with such an invalid input. – Dan Mašek May 18 '21 at 16:17
  • On a side note, you're using `drawContours` incorrectly. The second parameter should be a list of contours, but you're giving it only a single contour (list of points), so it will end up drawing just a bunch of dots. See https://stackoverflow.com/q/36311398/3962537 – Dan Mašek May 18 '21 at 16:43
  • 1
    @DanMašek you are right with the area. Damn I didn't notice that, as soon as I changed 5000 to 500 it just started to works – AntonP May 19 '21 at 07:23

1 Answers1

1

use this thats how i solved it.

import cv2
import numpy as np

cap = cv2.VideoCapture(1)
#widht id:3, height id:4, brightness id:10.
cap.set(3,640)
cap.set(4,480)
width,height = 640,480
def preprocessing(img):
    imgGray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    imgBlur = cv2.GaussianBlur(img,(5,5),1)
    imgCanny = cv2.Canny(imgBlur,150,150)
    kernel = np.ones((5,5))
    imgDial = cv2.dilate(imgCanny,kernel,iterations=2)
    imgErode = cv2.erode(imgDial,kernel,iterations=1)

    return imgErode

def contour(img):
    biggest = np.array([])
    maxArea = 0
    contours,hierarchy = cv2.findContours(img,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
    for cnt in contours:
        area = cv2.contourArea(cnt)
        if area > 5000:
            #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
    cv2.drawContours(imgcontour,biggest,-1,(255,0,0),20)
    return biggest

def reorder(myPoints):
    pass

def warp(img,biggest):
    pts1 = np.float32(biggest)
    pts2 = np.float32([[0, 0], [width, 0], [0, height], [width, height]])
    matrix = cv2.getPerspectiveTransform(pts1, pts2)
    imgout = cv2.warpPerspective(img,matrix,(width,height))
    return imgout

while True:
    success, img = cap.read()
    cv2.resize(img,(width,height))
    imgcontour = img.copy()
    imgThres = preprocessing(img)
    biggest = contour(imgThres)
    print(biggest)
    if biggest.size != 0:
        imgwarp = warp(img,biggest)
        cv2.imshow('video', imgwarp)
    else:
        cv2.imshow('video',imgThres)
    if cv2.waitKey(1) & 0xFF == 27:
        break
swastik
  • 31
  • 3