I'm trying to produce a project that converts raster(.tif,ijpg) files to Geotiff automatically. In the example image, I need to identify the area that I have drawn in red in the photo. To detect this, I tried steps such as edge detection, morphology operations, Canny, but I can't get the result I want in some Raster files. The images I left the link to are generally the same type and format. Only the geometric objects inside the rectangular area I want to detect vary from region to region. waiting for your suggestions.
The area I want to detect is the area drawn in red in the sample image. Example image
My Code:
import os
import cv2
import numpy as np
from matplotlib import pyplot as plt
path = "example/asd.tif"
image=cv2.imread(path)
image_area = image.shape[1]*image.shape[0]
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV cv2.THRESH_OTSU)[1]
close_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (15,3))
close = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, close_kernel, iterations=1)
dilate_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,3))
dilate = cv2.dilate(close, dilate_kernel, iterations=1)
cnts = cv2.findContours(dilate, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE)
cnts = imutils.grab_contours(cnts)
cnts = sorted(cnts, key=cv2.contourArea, reverse=True)[:5]
for c in range(len(cnts)):
rot_rect = cv2.minAreaRect(cnts[1])
(x,y),(w,h),angle = rot_rect
box = cv2.boxPoints(rot_rect)
box2 = np.int0(box)
if (1.3>h/w>1.2) and cv2.contourArea(box2)>image_area*50/100:
cv2.drawContours(image,[box2],0,(0,0,255),8)
cv2.imshow("rectangle",image)
cv2.waitKey(0)
As can be seen in the result image, the numbers on the sides of the rectangle area I want cause problems in perceiving the area I want. In some cases, when the edges of the rectangle are distorted, the program cannot detect it at all.
CodePudding user response:
I made it !
I got the detection area I wanted. The transactions I made;
Create gray image
Morphology expansion application
*Delete small areas
*Creating a higher kernel level image than an image with small areas deleted
*create a contour and create a bounding box to the 1st contour in the hierarchy
Result: Successful
My Code:
image = cv2.imread(file_path)
image2=image.copy()
origin_image=image.copy()
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
scale = image.shape[1]/image.shape[0]
#my screen resolution : 1920*1080
new_dimension = (int(1080*scale),1080)
image_area = image.shape[1]*image.shape[0]
opening = cv2.morphologyEx(gray, cv2.MORPH_OPEN, kernel = np.ones((3,3),np.uint8))
cnts = cv2.findContours(opening, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE)
cnts = imutils.grab_contours(cnts)
cnts = sorted(cnts, key=cv2.contourArea, reverse=True)
for c in range(len(cnts)):
[x, y, w, h] = cv2.boundingRect(cnts[c])
if w*h<5000:
cv2.rectangle(opening, (x, y), (x w, y h), (255, 255, 255), -1)
opening=cv2.morphologyEx(opening, cv2.MORPH_OPEN, kernel = np.ones((100,100),np.uint8))
cnts = cv2.findContours(opening, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE)
cnts = imutils.grab_contours(cnts)
cnts = sorted(cnts, key=cv2.contourArea, reverse=True)
rot_rect = cv2.minAreaRect(cnts[1])
(x,y),(w,h),angle = rot_rect
box = cv2.boxPoints(rot_rect)
box2 = np.int0(box)
cv2.drawContours(origin_image,[box2],0,(255,10,10),8)
# abc=cv2.polylines(origin_image,cnts[1],True, (255,10,10),15)
cv2.imwrite("xxx.tif",origin_image)
cv2.imshow("xxx",origin_image)
cv2.waitKey(0)