简体   繁体   English

我应该使用什么样的参数来查找和裁剪图像中的对象?

[英]What kind of parameters should I use to find and crop objects in an image?

I am new to deep learning and try to implement a ML algorithm for image clustering.我是深度学习的新手,并尝试实现用于图像聚类的 ML 算法。 The problem is that I can't crop the objects in an image in Python using OpenCV.问题是我无法使用 OpenCV 在 Python 中裁剪图像中的对象。 Here is the code I have implemented and it works for some objects if the color of the object is very different(in RGB values) from the background but it doesn't work for the image I need for ML algorithm.这是我已经实现的代码,如果 object 的颜色与背景非常不同(在 RGB 值中),它适用于某些对象,但它不适用于 ML 算法所需的图像。 What kind of parameters should I have/change?我应该拥有/更改什么样的参数? Any suggestions?有什么建议么?

import cv2
import numpy as np
from PIL import Image
import tkinter as tk
from tkinter import filedialog as fd
from tkinter import*
import random
#!/usr/bin/python
from PIL import Image
import sys


myFile = 'Path' + '/crop.png'
nr_of_im = 1
q = 0
r = 0
x_list = []
y_list = []
img = cv2.imread(myFile, cv2.IMREAD_UNCHANGED)

ret, thresh = cv2.threshold(cv2.cvtColor(img.copy(), cv2.COLOR_BGR2GRAY) , 30, 255, cv2.THRESH_BINARY)
contours, hier = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for contour in contours:
    print("len",len(contours))
    if cv2.contourArea(contour) > 80:
        x, y, w, h = cv2.boundingRect(contour)
        q = w
        r = h       
        x_list.append(x)
        y_list.append(y)
        font = cv2.FONT_HERSHEY_SIMPLEX
        ROI = img[y-10:y+10+h, x-10:x+10+w]
        ROI = cv2.resize(ROI,(300,300))
        file_all = "/images/%d.jpg"%nr_of_im
        nr_of_im += 1
        cv2.imwrite(file_all,ROI)

There are 21 objects in the image but the length of contours returns 1. The image looks like so图像中有 21 个对象,但轮廓的长度返回 1。图像看起来像这样

crop.png:作物.png:

作物.png

Your threshold is too low and produces a totally white image for me.您的阈值太低,为我生成了一个完全白色的图像。 You need to increase your threshold.你需要提高你的门槛。 Always view your thresholding to be sure it is working the way you expect.始终查看您的阈值,以确保它按您期望的方式工作。 You can always remove the viewing later.您以后可以随时删除查看。

The following works for me using Otsu thresholding with a threshold value of 97. I get 21 contours.以下适用于我使用阈值为 97 的 Otsu 阈值。我得到 21 个轮廓。

Input:输入:

在此处输入图像描述

import cv2
import numpy as np

# read image
img = cv2.imread('blocks.jpg')

# convert to grayscale
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

# threshold
ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
print(ret)

# apply morphology fill and separate large regions and remove small ones
kernel = cv2.getStructuringElement(cv2.MORPH_RECT , (9,9))
morph = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT , (15,15))
morph = cv2.morphologyEx(morph, cv2.MORPH_OPEN, kernel)

# get contours
result = img.copy()
contours = cv2.findContours(morph, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]

# get count of contours
print(len(contours))

# draw bounding boxes on contours
for cntr in contours:
    x,y,w,h = cv2.boundingRect(cntr)
    cv2.rectangle(result, (x, y), (x+w, y+h), (0, 0, 255), 2)
    #print("x,y,w,h:",x,y,w,h)
    
# save results
cv2.imwrite("blocks_thresh.jpg", thresh)
cv2.imwrite("blocks_morphology.jpg", morph)
cv2.imwrite("blocks_bboxes.jpg", result)

# show thresh and result    
cv2.imshow("thresh", thresh)
cv2.imshow("morph", morph)
cv2.imshow("result", result)
cv2.waitKey(0)
cv2.destroyAllWindows()

Threshold image:阈值图像:

在此处输入图像描述

Morphology cleaned image:形态清洁图像:

在此处输入图像描述

Resulting bounding boxes from contours:从轮廓生成的边界框:

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM