0

I want to perform operation on the region of my interest..that is central rectangular table which you can see in the image. I am able to give the co-ordinates of my region of interest manually and crop that part img = cv2.imread('test12.jpg',0) box = img[753:1915,460:1315]

but i want to crop that part automatically without giving the pixels or coordinates manually.Can anyone please help me with this?

http://picpaste.com/test12_-_Copy-BXqHMAnd.jpg this is my original image.

http://picpaste.com/boxdemo-zHz57dBM.jpg this is my cropped image. for doing this I entered the coordinates of the desired region and cropped. But , now i have to deal with many similar images where the coordinates of my region of interest will slightly vary. I want a method which will detect the table(my region of interest) and crop it. Currently I'm using this img = cv2.imread('test12.jpg',0) box = img[753:1915,460:1315] to crop my image.

  • You will need to use OpenCV to help you detect the edges of your table. How you do this depends on the image in question. Are you able to give a picture sample (or at least a link to one until you have enough reputation). – Martin Evans Jul 07 '15 at 08:53
  • http://picpaste.com/test12_-_Copy-BXqHMAnd.jpg thisis the link to my image. And yes I'm using opencv . But I am a beginner in both python and image processing.. so I need to know how exactly to get my region of interest. – yash Wanth Shetty Jul 07 '15 at 09:59
  • @MartinEvans can you please help me with a piece of code..? – yash Wanth Shetty Jul 07 '15 at 10:12
  • your two links are dead. – snoob dogg Apr 20 '18 at 22:18

2 Answers2

1

You could try using the openCV Template Matching to find the coordinates of your rectangular table within the image. Template Matching

The following is a test program to find the coordinates for images I am trying to find.

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

try:
    img = cv2.imread(r'new_webcam_image.jpg',0)
    template = cv2.imread(r'table_template.jpg',0)
except IOError as e:
    print("({})".format(e))
else:
    img2 = img.copy()
    w, h = template.shape[::-1]

# All the 6 methods for comparison in a list
 methods = ['cv2.TM_CCOEFF', 'cv2.TM_CCOEFF_NORMED', 'cv2.TM_CCORR',
             'cv2.TM_CCORR_NORMED', 'cv2.TM_SQDIFF', 'cv2.TM_SQDIFF_NORMED']


for meth in methods:
    img = img2.copy()
    method = eval(meth)

    # Apply template Matching
    res = cv2.matchTemplate(img,template,method)
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
    print("Method: %s" , meth)
    print("min_val: " , min_val)
    print("max_val: " , max_val)
    print("min_loc: " , min_loc)
    print("max_loc: " , max_loc)
    print(" ")
    # If the method is TM_SQDIFF or TM_SQDIFF_NORMED, take minimum
    if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:
        top_left = min_loc
    else:
        top_left = max_loc
    bottom_right = (top_left[0] + w, top_left[1] + h)

    cv2.rectangle(img,top_left, bottom_right, 255, 2)

    plt.subplot(121),plt.imshow(res,cmap = 'gray')
    plt.title('Matching Result'), plt.xticks([]), plt.yticks([])
    plt.subplot(122),plt.imshow(img,cmap = 'gray')
    plt.title('Detected Point'), plt.xticks([]), plt.yticks([])
    plt.suptitle(meth) #; plt.legend([min_val, max_val, min_loc, max_loc], ["min_val", "max_val", "min_loc", "max_loc"])

    plt.show()
    box = img[top_left[1]:top_left[1]+h,0:bottom_right[1]+w]
    cv2.imshow("cropped", box)
    cv2.waitKey(0)
Steven Correia
  • 461
  • 10
  • 18
  • Thanks for your reply, I tried run the code which you have given but i got this error `w, h = template.shape[::-1]` `AttributeError: 'NoneType' object has no attribute 'shape'` @scorreia – yash Wanth Shetty Jul 07 '15 at 10:15
  • 1
    I'm guessing it failed to find your image. I suggest you add a full path to it. – Martin Evans Jul 07 '15 at 11:40
  • Yes, now it worked! now, how can i crop and save the part of the image which has been matched?? – yash Wanth Shetty Jul 07 '15 at 11:43
  • You should be able to use the parameters `min_val, max_val, min_loc, max_loc` to find the coordinates you need to crop based on the known size of your template image. Similar to the `cv2.rectangle(img,top_left,bottom_right, 255, 2)` call, which would outline the template on the original image. – Steven Correia Jul 07 '15 at 11:49
  • Can you please tell me the syntax for that? I'm getting those parameters which you mentioned above when I run the code.. now How exactly can I use them to crop the desired part? – yash Wanth Shetty Jul 07 '15 at 11:52
  • Check out this tutorial http://www.pyimagesearch.com/2014/01/20/basic-image-manipulations-in-python-and-opencv-resizing-scaling-rotating-and-cropping/ or look at this previous answer for some hints http://stackoverflow.com/a/15589825/5066845 – Steven Correia Jul 07 '15 at 11:56
  • but, i dont want to enter the coordinates manually and crop.. is it possible to automate it so that i get a cropped image just after my template is matched? – yash Wanth Shetty Jul 07 '15 at 12:03
  • Maybe I don't understand what you mean by manually. I would use the coordinates found during template matching in order to crop the image. Wouldn't that be the next step in automating, which is done by the code? – Steven Correia Jul 07 '15 at 12:10
  • But I need to enter the coordinates found during template matching inorder to crop everytime..when i use different images for test..then evrytime i want to crop i need to enter the found out coordinates..ryt?? – yash Wanth Shetty Jul 07 '15 at 12:24
  • Could you edit your question to provide an example of the before image and a cropped image? Maybe you could also describe your set-up to make it easier to understand. What have you tried already? – Steven Correia Jul 07 '15 at 12:30
  • This might not be correct, you will have to test it... you can use the template example to get the coordinates of the image you want to crop, then write something like `box = img[top_left:top_left+h,bottom_right-w:bottom_right]` and save the box as another cropped image. – Steven Correia Jul 07 '15 at 12:57
  • `box = img[top_left:top_left+h , bottom_right-w:bottom_right]` `TypeError: can only concatenate tuple (not "int") to tuple`.. i got this error – yash Wanth Shetty Jul 07 '15 at 14:48
  • For the future, you should show more of what you tried yourself, this site is not designed to ask for a complete solution. But you can try this, but _you_ will need to modify it to fit your needs! `box = img[top_left[1]:top_left[1]+h,0:bottom_right[1]+w]` – Steven Correia Jul 07 '15 at 15:08
  • Wow Thanks a lot! that worked .. I modified that a bit and i got exactly what I wanted. – yash Wanth Shetty Jul 07 '15 at 15:18
  • You're welcome, if you could accept this as the answer I would really appreciate it :) – Steven Correia Jul 07 '15 at 19:23
0

I don't have a full solution for you. The code shown was based on some code I was using to fix output from a scanner. The template solution to me sounds like a better approach, but the following should give you something else to work with.

import cv2

imageSrc = cv2.imread("test12.jpg")

# First cut the source down slightly
h = imageSrc.shape[0]
w = imageSrc.shape[1]
cropInitial = 50
imageSrc = imageSrc[100:50+(h-cropInitial*2), 50:50+(w-cropInitial*2)]

# Threshold the image and find edges (to reduce the amount of pixels to count)
ret, imageDest = cv2.threshold(imageSrc, 220, 255, cv2.THRESH_BINARY_INV)
imageDest = cv2.Canny(imageDest, 100, 100, 3)

# Create a list of remaining pixels
points = cv2.findNonZero(imageDest)

# Calculate a bounding rectangle for these points
hull = cv2.convexHull(points)
x,y,w,h = cv2.boundingRect(hull)

# Crop the original image to the bounding rectangle
imageResult = imageSrc[y:y+h,x:x+w]
cv2.imwrite("test12 cropped.jpg", imageResult)

The output does not crop as much as you need. Playing with the various threshold parameters should improve your results.

I suggest using imshow at various points on imageThresh and imageDest so you can see what is happening at each stage in the code. Hopefully this helps you progress.

Martin Evans
  • 45,791
  • 17
  • 81
  • 97
  • Thanks I tried both your code and template matching, and yes Template maching seems to work. but In the tempate maching code mentioned in the other comment How can I crop and save the matched part after template matching?? – yash Wanth Shetty Jul 07 '15 at 11:39