Reputation: 795
What would be the best method (using python and OpenCV) of finding the lowest corner ( not edge ) of towel in this images? Also, the towel color can be different, but the background color will be always the same.
And I need this corner ( the lowest "real" towel corner ):
Upvotes: 4
Views: 1152
Reputation: 21203
Since you have approximately two distinct colors in the image (one each for foreground and background) you could convert your image to HSV color space and visualize each of the individual channels.
Code:
path = r'C:\Users\Desktop'
filename = 'towel.jpg'
img = cv2.imread(os.path.join(path, filename))
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) #--- convert to HSV
cv2.imshow('hsv.jpg', hsv)
h = hsv[:,:,0]
cv2.imshow('h.jpg', h) #--- visualize the hue channel
ret, thresh = cv2.threshold(h, 0, 255, cv2.THRESH_OTSU + cv2.THRESH_BINARY_INV)
cv2.imshow('thresh1', thresh) #--- apply Otsu threshold on hue channel
Notice that white blob in the center of the towel, it has to be removed. For that purpose I have used morphological opening.
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(25, 25))
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
cv2.imshow('fin', cv2.bitwise_not(opening))
OpenCV provides the functionality to find top, bottom, right-most and left-most corners for a given contour. I obtained the contour of the final resulting image and found the four extreme points.
Code:
im2, contours, hierarchy = cv2.findContours(cv2.bitwise_not(opening), cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) #--- finding contours
cnt = contours[0] #--- since there is only one contour present
leftmost = tuple(cnt[cnt[:,:,0].argmin()][0])
rightmost = tuple(cnt[cnt[:,:,0].argmax()][0])
topmost = tuple(cnt[cnt[:,:,1].argmin()][0])
bottommost = tuple(cnt[cnt[:,:,1].argmax()][0])
print('The extreme points are leftmost: {}, rightmost: {}, topmost: {} and bottommost: {}'.format(leftmost, rightmost, topmost, bottommost))
The extreme points are leftmost: (32, 336), rightmost: (807, 439), topmost: (459, 12) and bottommost: (699, 743)
I have also marked the extreme points on a copy of the original image:
img2 = img.copy()
cv2.circle(img2, leftmost, 5, (0, 255, 255), -1) #-- leftmost
cv2.circle(img2, rightmost, 5, (0, 255, 255), -1) #-- rightmost
cv2.circle(img2, topmost, 5, (0, 255, 255), -1) #-- topmost
cv2.circle(img2, bottommost, 5, (0, 255, 255), -1) #-- bottommost
Upvotes: 6
Reputation: 1258
You can use the canny edge detector. For to detect the corner of the image.I have given you the link of 2 sources below.
Code:
import cv2
import matplotlib.pyplot as plt
im = cv2.imread('boat.png')
edges = cv2.Canny(im,25,255,L2gradient=False)
plt.imshow(edges,cmap='gray')
plt.show()
Upvotes: 0
Reputation: 5002
what you are looking for is edge detection algorithm.
Use the below code from the following Link
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
img = cv.imread('Your towel image.jpg',0)
edges = cv.Canny(img,100,200)
plt.subplot(121),plt.imshow(img,cmap = 'gray')
plt.title('Original Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(edges,cmap = 'gray')
plt.title('Edge Image'), plt.xticks([]), plt.yticks([])
plt.show()
Upvotes: 0