Angad Sobti
Angad Sobti

Reputation: 1

OpenCV Error: Assertion failed (contour.checkVector(2) >= 0 && (contour.depth() == CV_32F || contour.depth() == CV_32S)) in contourArea

This is code for virtual dressing room So basically for running this code ubuntu 12.04 , python 2.7.3, gtk2 and opencv 2 is used. It removes background screen, detects T-shirt in almost any light conditions, replaces T-shirt color.It is written to replace shirt and design on the shirt .It works for blue shirt in green background.

On running the code I found the following error-

> **OpenCV Error: Assertion failed (contour.checkVector(2) >= 0 && (contour.depth() == CV_32F || contour.depth() == CV_32S)) in contourArea, file /build/buildd/opencv-2.3.1/modules/imgproc/src/contours.cpp, line 1673**
Traceback (most recent call last):
  File "vdr/main.py", line 179, in display_frame
    self.final=self.getOutput_frames()
  File "vdr/main.py", line 224, in getOutput_frames
    res=self.replace.replace_design(cntr,self.p_mat, self.design_template, res)
  File "vdr/color_replace.py", line 49, in replace_design
    area.append(cv2.contourArea(cntr[i].astype('int')))
cv2.error: /build/buildd/opencv-2.3.1/modules/imgproc/src/contours.cpp:1673: error: (-215) contour.checkVector(2) >= 0 && (contour.depth() == CV_32F || contour.depth() == CV_32S) in function contourArea

In the code there is some problem in detecting the contours of the Tshirt.

The code in main.py for getOutput_frames is as follows-

        def getOutput_frames(self):
            if TEST_MODE:
               _,frame=self.vid.read() #NOTE: Testing without camera. uncomment this to feed from camera.
            else:
                frame=self.v.outFrame() #NOTE: feeding from Camera.

            self.norm.getRGB(frame) #input to Normalized RGB

            norm_rgb=self.norm.normalized() #normalized RGB
            print 'Got normalized RGB '       
            rgb_planes=self.v.imagePlanes(norm_rgb)

            self.back.loadBackground()
            self.back.getFrames(rgb_planes[1])
            self.back.subtract_back(norm_rgb)

            subtracted=self.back.remove(frame)
            print 'background subtracted now'

            self.tshirt.getFrames(norm_rgb)
            mask,cntr=self.tshirt.detect_shirt()
            print 'found tshirt'

            self.replace.getFrames(subtracted,mask)

            res=self.replace.replace_color(self.color)

            if self.design is not 7:
                res=self.replace.replace_design(cntr,self.p_mat, self.design_template, res)

            #replace.replace_design(cntr, p_mat,design_template,res)

            #cv2.imshow("subtracted", res)

            return res

In tshirt.py code for detectshirt is as follows-

    def detect_shirt(self):


              #self.dst=cv2.inRange(self.norm_rgb,np.array([self.lb,self.lg,self.lr],np.uint8),np.array([self.b,self.g,self.r],np.uint8))
             self.dst=cv2.inRange(self.norm_rgb,np.array([20,20,20],np.uint8),np.array([255,110,80],np.uint8))
            cv2.threshold(self.dst,0,255,cv2.THRESH_OTSU+cv2.THRESH_BINARY)
            fg=cv2.erode(self.dst,None,iterations=2)
            #cv2.imshow("fore",fg)  
            bg=cv2.dilate(self.dst,None,iterations=3)
            _,bg=cv2.threshold(bg, 1,128,1)
            #cv2.imshow("back",bg)

            mark=cv2.add(fg,bg)
            mark32=np.int32(mark)
            cv2.watershed(self.norm_rgb,mark32)
            self.m=cv2.convertScaleAbs(mark32)
            _,self.m=cv2.threshold(self.m,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
            #cv2.imshow("final_tshirt",self.m)

           cntr,h=cv2.findContours(self.m,cv2.cv.CV_RETR_EXTERNAL,cv2.cv.CV_CHAIN_APPROX_SIMPLE)


            return self.m,cntr

In color_replace.py the code for replace_design is as follows

         def replace_design(self,cntr,p_mat,design_template,input_image):
                area=list()

                for i in range(len(cntr)):

                    area.append(cv2.contourArea(cntr[i].astype('int')))

                max_area=max(area)

                for i in range(len(area)):
                    if max_area==area[i]:
                        index=i
                mom=cv2.moments(cntr[index].astype('int'))
                #print mom
                x=mom['m10']
                y=mom['m01']
                cx=int(x/max_area)
                cy=int(y/max_area)
                #print 'center-X',cx
                #print 'center-Y',cy

                rect=cv2.boundingRect(np.array(cntr[index],np.float32))

                x=rect[0]
                y=rect[1]
                w=rect[2]
                h=rect[3]

                q=np.array([
                            [x+w/3,(y+h)/3],
                            [x+w/2,(y+h)/3],
                            [x+w/2,y+h/3],
                            [x+w/3,y+h/3]
                       ],np.float32)


                mat=cv2.getPerspectiveTransform(p_mat,q)

                   dst=cv2.warpPerspective(design_template,mat(config.width,config.height))


                temp=cv2.cvtColor(input_image,cv2.cv.CV_BGR2BGRA)
                temp=cv2.addWeighted(temp,1.0,dst,1.0,1.0)       
                res=cv2.cvtColor(temp,cv2.cv.CV_BGRA2BGR)

                return res 

Could you please help me resolve this error . The entire code is available on- entire Code of virtual dressing room

Upvotes: 0

Views: 767

Answers (1)

api55
api55

Reputation: 11420

The error tells you that the list passed is either empty or not with int/float. Then, the solution is:

1) check for empty lists -> this may happen if their is a post-processing of the contours. I think it is not possible if it is unchanged.

2) the list have to be int or float. You use astype with int, normally OpenCV relies on numpy types, so probably is better to use np.int32 instead. Also, if it was not change from the findContours function, it is not needed astype at all. They are already int values.

Upvotes: 1

Related Questions