Help translate c++ to python | nearest points | line | polylines [closed]

asked 2015-09-22 04:39:25 -0600

marcoE gravatar image

I asked a question about contours, and how to fill blank spaces with "dashed" contour. @LBerger and @sturkmen gently gave me solutions, and I choose the @sturkmen code ( http://pastebin.com/EXuKpgY6 ) because it is easier to implement. However, both are in c++. The original image is : image description

The desired output (which is also the @sturkmen code's ouput) is : image description

Taking in account stakeoverflow answers, @sturkmen 's help and @berak 's code/answer http://answers.opencv.org/question/71... I was able to do some translation.

In order to simplify my problem I used the @berak 's image:

image description

My current code stands as :

import cv2
import numpy as np

def distanceBtwPoints(p0, p1):
    return np.sqrt((p0[0] - p1[0])**2 + (p0[1] - p1[1])**2)

def findNearestPointIndex(pt, Points):
    mindistance = 1e9

    for ip in Points:
        print "ip", ip
        print "pt", pt
        distance = distanceBtwPoints(pt, ip)
        print 'distance', distance

        if distance < mindistance :
            mindistance =  distance
            nearestpoint = ip
            print "nearestpoint", nearestpoint
            nearestpointindex = nearestpoint.argmin()
            print "nearestpointindex", nearestpoint.argmin()

    return  nearestpointindex

if __name__ == '__main__':
    img = cv2.imread("bridgeTestSource.png")
    src = cv2.imread("bridgeTestSource.png")

    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    gray = np.asarray(gray < 127, dtype=np.uint8) # need to cast back to uint8

   contours, hierarchy = cv2.findContours(gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
   cv2.drawContours(img, contours,-1, (0,0,255), 2)
   for i in range(len(contours)):
        print "Contour ", i , "points", contours[i]
        print
        print " - Contour ", i, "area :", cv2.contourArea(contours[i])
        print
        for j in range(contours[i].shape[0]):
            print "contour x y", contours[i][j].squeeze()
           print "the contour" , i, "distance between ", contours[i][0].squeeze(),contours[i][1].squeeze(), "is " , distanceBtwPoints(contours[i][0].squeeze(), contours[i][1].squeeze())


    cnt = contours[0]

    for c in contours:
        if cv2.contourArea(cnt) < cv2.contourArea(c):
            cnt = c 

    for c in contours:
        if not np.array_equal(cnt, c) and c.shape[0] > 0:
            for j in range(c.shape[2]):
                pt0 = c[j][0]
                cnt_nearIdx = cnt[findNearestPointIndex(pt0, cnt.squeeze())].squeeze()

                lcnt_nearIdx = cnt_nearIdx.tolist()
                lpt0 = pt0.tolist()

                tcnt_nearIdx = tuple(lcnt_nearIdx)
                tpt0 = tuple(lpt0)

                cv2.line(img,tpt0, tcnt_nearIdx,(0,0,0),1,8)

    cv2.imwrite('nimg.jpg', img)
    gray_src = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
    gray_src = np.asarray(gray_src < 127, dtype=np.uint8) # need to cast back to uint8

    contours1, hierarchy = cv2.findContours(gray_src, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    cv2.drawContours(src, contours1,-1, (0,0,0), 0)

    m_xor= np.ones(src.shape[:2], dtype="uint8") * 255

    ncnt = cnt.astype(np.int32)
    cv2.polylines(m_xor, [ncnt], 1, (0,0,0))

   m_xor = 255 - (src or m_xor)

   cv2.imwrite('result.jpg', m_xor)

And I'm facing problems. The image after the lines loop is a mess:

image description

I'm getting errors in m_xor: m_xor = 255 - (src or m_xor) ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

For debug purposes you can see my distance, points, nearest here: http://pastebin.com/NstQXxBk

edit retag flag offensive reopen merge delete

Closed for the following reason the question is answered, right answer was accepted by sturkmen
close date 2020-09-24 18:46:28.267627

Comments

src or m_xor <-- that's || . did you mean like cv2.bitwise_or() ?

pt0 = c[j][0] why only the x coord ? did you mean pt0 = c[j]

berak gravatar imageberak ( 2015-09-22 07:04:49 -0600 )edit
1

not or it must be xor

the part of c++ code:

Mat m_xor(src.size(),CV_8UC1,255);
polylines(m_xor,contour,false,color,1,LINE_8);

m_xor = 255 - (src ^ m_xor) ;
sturkmen gravatar imagesturkmen ( 2015-09-22 07:29:47 -0600 )edit

cv2.bitwise_xor ?

I think that I have an error drawing lines. I'm afraid that one of the loops (at least) is wrong

marcoE gravatar imagemarcoE ( 2015-09-22 07:42:03 -0600 )edit

I did an update on my code: http://pastebin.com/an8AQT5b

I still have problems in the xor part. However, the ouput after the lines loop is different https://dl.dropboxusercontent.com/u/7...

marcoE gravatar imagemarcoE ( 2015-09-22 08:23:16 -0600 )edit

the result image is almost OK !

it must be like : image description

sturkmen gravatar imagesturkmen ( 2015-09-22 08:37:50 -0600 )edit

updated code: http://pastebin.com/t0abJyNc Result : https://dl.dropboxusercontent.com/u/7...

I think it is close, @berak do you know what it is wrong? @sturkmen is it close?

marcoE gravatar imagemarcoE ( 2015-09-22 09:11:35 -0600 )edit

@sturkmen intermediate result update : https://dl.dropboxusercontent.com/u/7...

The final remains similar, probably I'm not doing the same bitwise operation in python that you have done on c++ python code: http://pastebin.com/t0abJyNc

marcoE gravatar imagemarcoE ( 2015-09-22 09:17:12 -0600 )edit

Code updated: http://pastebin.com/WhsQUQLQ I think this almost done. Sadelly It is not working a simple inversion : My result image is : https://dl.dropboxusercontent.com/u/7... So, I thought, I just need an inversion! But the inversion result is: https://dl.dropboxusercontent.com/u/7...

@sturkmen and @berak thank you for your support, It is almost finished, I just need the final help!

marcoE gravatar imagemarcoE ( 2015-09-22 10:39:16 -0600 )edit

@sturkmen is this https://dl.dropboxusercontent.com/u/7... the result to the @berak 's image ?

marcoE gravatar imagemarcoE ( 2015-09-23 04:39:05 -0600 )edit
sturkmen gravatar imagesturkmen ( 2015-09-23 05:36:14 -0600 )edit

now the time to try CHAIN_APPROX_NONE ( as in c++ code )

contours, hierarchy = cv2.findContours(gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
sturkmen gravatar imagesturkmen ( 2015-09-23 05:40:00 -0600 )edit

https://dl.dropboxusercontent.com/u/7...

in both contours? In the first one the approx is none and second one is simple

marcoE gravatar imagemarcoE ( 2015-09-23 09:51:54 -0600 )edit

:) why you did not look to my c++ code. use CHAIN_APPROX_NONE with all findContours. is that image output of your pyhon code?

sturkmen gravatar imagesturkmen ( 2015-09-23 10:12:45 -0600 )edit

@sturkmen yes it is.

marcoE gravatar imagemarcoE ( 2015-09-24 04:30:11 -0600 )edit