Edge -1 using erode and dilate (Python)

Asked

Viewed 292 times

0

I’m having difficulty creating an edge with -1 pixels around what was labeled in the image. Where 255 is what has been labeled and around this area of 255 I want to put -1 which will be an edge to be ignored in training. I’m trying to use erode in the image. png and then use Dilation on top of the erode to create that edge, but I can in no way modify the value that the edge created by them will receive. I tried to use borderType, but it was not effective.

Follow the current code:

import cv2

import numpy as np

img = cv2.imread('frame22.png',0)

kernel = np.ones((5,5),np.uint8)

erosion = cv2.erode(img,kernel,iterations = 1)

dilationcomerosion = cv2.dilate(erosion,kernel,iterations = 1)

cv2.namedWindow("Input", cv2.WINDOW_NORMAL)

cv2.namedWindow("dilationcomerosion", cv2.WINDOW_NORMAL)

cv2.imshow('Input', img)

cv2.imshow('dilationcomerosion', erosion)

cv2.waitKey(0)

Segue imagem do array da variável apos a execução do dilate em cima do erosion:

Input

Dilate em cima do Erode

frame22.png

  • Please [Edit] the question with the image "frame22.png". And I found it confusing, what would -1? -1 be in the coordinates? In the erode algorithm? In the color channel of each pixel?

  • I would like the value in the coordinate to be changed to -1, in short to create an edge of -1 around what was labeled with 255, so I imagine it is better to change the value of the coordinate to 0 apra -1.

  • The coordinates are the x and y axes, the numbers 500 and few in your image. The 0 and 255 is the binary color of each pixel, where 0 is black and 255 white. That’s why when you put -1 in this color channel, Opencv will return an error. Because in Opencv the range of binary colors is 0 or 255... However, you can change these values in numpy and view in Pycharm or another library like matplotlib.pyplot

  • In case then to do what I need, it is necessary to change the value of the coordinate even right? As there is no color value -1 will give error. I can make that change with this informed library?

  • The coordinate is the position of each pixel in a matrix, i.e., (x,y) and each pixel has the following information (x,y, colors). In which colors varies according to the color space used, if binary has only one channel. But if it is colored in the RGB color space, for example, colors will be [R,G,B]. I think your question is confused because you do not understand very well how computer vision works, try to study the basic and theoretical part to better understand.

  • Yes I know, I understood what you meant, but I think you could not understand my question clearly, I know that each pixel is followed by (x, y, color). the real intention is simply to be able to make an edge that will be ignored in training, so I would have to modify this value to -1 which is the ignored value in the training algorithm, but I can’t find options for how to create that edge to be ignored, so much so that I’ve spent a lot of time on erode, dilate and gradient..

Show 2 more comments

1 answer

2


Problem

Images are uploaded by Opencv as unit8, for more information on data types read this link from Numpy.

Therefore, they are unsigned int, that is, they have no sign (negative number). So by replacing the matrix value with -1, Python automatically considers -1 as 255, -2 as 254 and so on.

To solve this, you need to convert the matrix to another type of data.

Code

import cv2
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
import urllib.request


def mostrar_imagem(img):
    plt.imshow(img)
    plt.colorbar()
    plt.show()

#Inicialização
# Carregar imagem da internet
resp = urllib.request.urlopen("https://i.stack.imgur.com/gVDrL.png")
img = np.asarray(bytearray(resp.read()), dtype="uint8")
img = cv2.imdecode(img, cv2.IMREAD_COLOR)

# Converte para escala de cinza
cinza = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Obtém o binário
_, binario = cv2.threshold(cinza, 90, 255, cv2.THRESH_BINARY)
# Cria uma cópia para manter a original
copia = img.copy()

#procurar os contornos, procura contornos dentro dos contornos, aproxima os contornos
tmp = cv2.findContours(binario, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# compatibilidade entre versões diferentes do OpenCV
contornos = tmp[0] if len(tmp) == 2 else tmp[1]
#retorna 3 parametros, 1)imagens, 2contornos,3) hierarquia dos contornos

#Conversão de escala de cinza para BGR
img_contornos = cv2.cvtColor(cinza, cv2.COLOR_GRAY2BGR)

#Desenha os contornos
#imagem, contornos, (-1) são todos, a cor, espessura
cv2.drawContours(img_contornos, contornos, -1, (0, 255, 0), 1)
mostrar_imagem(img_contornos)

# Extrai somente o contorno de espessura 1 px
mask = cv2.inRange(img_contornos, (0, 254, 0), (0, 255, 0))
mostrar_imagem(mask)

# Substitui os valores da máscara por -1
binario = np.int16(binario)
binario[mask == 255] = -1

# Mostrar os valores -1 como cor branca
binario = np.ma.masked_where(binario == -1, binario)
cmap = matplotlib.cm.Greys  # Can be any colormap that you want after the cm
cmap.set_bad(color='red')
plt.imshow(binario, cmap=cmap)
plt.show()

Explanation

  1. Upload the image;
  2. Converts the image to binary, because the findcontours uses an algorithm for images with a color channel;
  3. Find the image borders;
  4. Draw the border with 1 pixel thickness: Contorno
  5. Create a mask by extracting the contours: Máscara
  6. Converts the image to int16;
  7. Replace with -1 on the binary image, the pixels with a value of 255 on the mask image.
  8. Set the pixels to -1 for the red color in the matplotlib library viewer.

Resultado

  • To read a file directly from the folder where the code is for example, using cv2, I can do img.imread("filename",0), I tried to use so, however it did not work, you indicate some other function that does this, in case change: Resp = urllib.request.urlopen("https://i.stack.Imgur.com/gVDrL.png") img = np.asarray(bytearray(Resp.read()), dtype="uint8") for any function that I can read from the image folder instead of the url and that code still works. I think this code solves my problem well (because I was able to apply erode and dilate on it, it has improved a lot).

  • In what format are your images, I took as the pattern that you sent. But if they’re already in binary, you don’t need to convert them to binary color space.

  • The images are in PNG format.

  • When you read the image withimread(img, 0) you are creating an array in the grayscale color space. As if it were cinza in the code

  • Got it, and you suggest some other function that reads the folder file, but that this code that you sent keep working? I tried a few, but to no avail. #Resp = cv2.imread("frame22.png", 0) #Resp = plt.imread('frame22.png') #Resp = Image.open('frame22.png') #Resp = plt.imread("frame22.png", format=None) #that can read, ams from the error in the bytray readear #Resp = mpimg.imread("frame22.png")

  • Try cinza = cv2.imread("frame22.png", 0) and remove the other part of the code. As I said before, I don’t think you understand the basic part of computer vision. See a little of the incial part, it is worth it, because the color spaces and the types of data you will have to understand in any application you will make with images.

  • Okay, I’m gonna take a look at this, I’m still good at the beginning, so there’s a few things I’m not quite sure about.

  • I tried the suggested change, but still it returns me error in bytearray(Resp.read()) that I changed to bytearray(gray.read()), or is this part not necessary either? Attributeerror: 'numpy.ndarray' Object has no attribute 'read'

  • I made a changes here and it worked out to read the PNG file straight from the folder. img = cv2.imread('frame22.png',0) #remove gray, as it is already grayscale read by . imread() # Converts to grayscale #gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) _, binary = cv2.Threshold(img, 90, 255, cv2.THRESH_BINARY) img_contours = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) These were the changes I made, that worked and got the same result.

Show 4 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.