Search code examples
pythonimagepython-2.7opencvpixel

detect 4 interesting pixels


I read this picture using OpenCV:

enter image description here

I detect the boundaries of the objects inside it and display the picture:

enter image description here

Here is my code:

import cv2
import numpy as np
from matplotlib import pyplot as plt


im=cv2.imread('db/4.jpg')
#mask=np.zeros(img.shape[:2],np.uint8)
imgray=cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
ret,thresh=cv2.threshold(imgray,242,245,235)
contours,hierarchy=cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)

cv2.drawContours(im,contours,-1,(0,255,0),3)
cv2.imshow("GL",im)
cv2.waitKey(0)
cv2.destroyAllWindows()

What I want to do:

I want to have the coordinates of 4 pixels belonging to one of the contours and:

  • First one is the closet from the X axis
  • Second one is the farest from the X axis
  • Third one is the closet from the Y axis
  • Fourth one is the farest from the Y axis

Note that the number of contours variable in my code can vary depending on the picture I read.


Solution

  • You can stack all contours into one array green and search for the minimum/maximum x/y value:

    green = np.vstack(contours).reshape((-1, 2))
    print "Min X:", green[np.where(green[:, 0] == green[:, 0].min()), :]
    print "Man X:", green[np.where(green[:, 0] == green[:, 0].max()), :]
    print "Min Y:", green[np.where(green[:, 1] == green[:, 1].min()), :]
    print "Man Y:", green[np.where(green[:, 1] == green[:, 1].max()), :]
    

    Note that, especially for the rectangle, there are multiple pixels meeting your requirement, because they have equal distance from the x or y axis.

    Here is a visualization of the "four" pixels:

    enter image description here

    The generating PyLab code:

    pl.imshow(im)
    pl.gca().autoscale(False)
    minX = np.where(green[:, 0] == green[:, 0].min())
    maxX = np.where(green[:, 0] == green[:, 0].max())
    minY = np.where(green[:, 1] == green[:, 1].min())
    maxY = np.where(green[:, 1] == green[:, 1].max())
    pl.plot(green[minX, 0], green[minX, 1], 'ro')
    pl.plot(green[maxX, 0], green[maxX, 1], 'go')
    pl.plot(green[minY, 0], green[minY, 1], 'bo')
    pl.plot(green[maxY, 0], green[maxY, 1], 'yo')