0

please help me, I need to insert an image on the substrate.

substrate:

enter image description here

It png, and in the area that is blank with cities, you must insert the image from edge to edge of the frame.

The problem is that I can't find an example of how to insert an image to the known coordinate points of the corners of a given substrate.

Pls help))

My test image

enter image description here


import cv2
import numpy as np
from skimage import io      

frame = cv2.cvtColor(io.imread('as.png'), cv2.COLOR_RGB2BGR)
image = cv2.cvtColor(io.imread("Vw5Rc.jpg"), cv2.COLOR_RGB2BGR)

mask = 255 * np.uint8(np.all(frame == [0, 0, 0], axis=2))

contours, _ = cv2.findContours(mask, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
cnt = min(contours, key=cv2.contourArea)
(x, y, w, h) = cv2.boundingRect(cnt)

# Copy appropriately resized image to frame
frame[y:y+h, x:x+w] = cv2.resize(image, (w, h))

cv2.imwrite('frame.png', frame)

I'm trying to find the area where to insert the image by color, the red color of the area I can find, and if there is no color?

The static frame has a constant size.

Denis
  • 158
  • 14
  • Welcome to Stack Overflow. Please take the **tour** and read the information guides in the **help center** (https://stackoverflow.com/help). Users are much more likely to help if you (1) show some research effort on your own, and (2) learn how to ask questions. Please provide a minimal, complete, and verifiable example to your specific problem. What have you tried so far? With regard to your question, just measure the corner of the grid in your substrate. Then get the corners of the colored image. Then use perspective warping to align and merge the two by multiplication. – fmw42 Oct 29 '19 at 04:59
  • @fmw42 Updated) – Denis Oct 29 '19 at 05:29
  • I do not see any red color. – fmw42 Oct 29 '19 at 06:10
  • @fmw42 When I tried the frame was red, now the frame is as shown in 1 figure – Denis Oct 29 '19 at 06:21
  • @fmw42 For rurther reading regarding the red frame, see [this Q&A](https://stackoverflow.com/questions/58556507/insert-the-picture-into-the-frame). Regarding this problem: Your substrate seems to have some transparency exactly where you want to embed your image. So, use `cv2.imread` with the `cv2.IMREAD_UNCHANGED` mode to load the substrate with alpha channel, find the appropriate ROI using the alpha channel and then insert your image there. If you get stuck, at least provide the desired output. Do you want to maintain the cities, the grid, etc. ABOVE the inserted image? – HansHirse Oct 29 '19 at 06:54
  • @HansHirse Yes I want to do so that you can see the city – Denis Oct 29 '19 at 08:14
  • `@HansHirse` Thanks for the link. I was totally confused by where he mentioned "red". – fmw42 Oct 29 '19 at 16:16

1 Answers1

2

Here is one way to do it in Python/OpenCV, if I understand what you want.

Read the substrate and trees images

Extract the alpha channel from the substrate

Extract the substrate image without the alpha channel

Use the alpha channel to color the base substrate image white where the alpha channel is black to correct a flaw in the base image

Threshold the alpha channel and invert it

Use morphology to remove the grid lines so that there is only one "outer" contour.

Extract the contour and its bounding box

Resize the trees image to the size of the bounding box.

Use numpy indexing and slicing to multiply the region of the substrate with the resized trees image.

Save the results.

Optionally, display the various images.


Substrate Image:

enter image description here

Trees Image:

enter image description here

import cv2
import numpy as np

# load substrate with alpha channel
substrate = cv2.imread("substrate.png", cv2.IMREAD_UNCHANGED)
hh, ww, cc = substrate.shape

# load colored image
trees = cv2.imread("trees.jpg")

# make img white where alpha is black to merge the alpha channel with the image
alpha = substrate[:,:,3]
img = substrate[:,:,0-2]
img[alpha==0] = 255
img = cv2.merge((img,img,img))

# threshold the img
ret, thresh = cv2.threshold(alpha,0,255,0)

# invert thresh
thresh = 255 - thresh

# make grid lines white in thresh so will get only one contour
kernel = np.ones((9,9), np.uint8)
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)

# find one outer contour
cntrs = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cntrs = cntrs[0] if len(cntrs) == 2 else cntrs[1]

# get bounding box of contour of white rectangle in thresh
for c in cntrs:
    x,y,w,h = cv2.boundingRect(c)
    #cv2.rectangle(img, (x,y), (x+w,y+h),(0, 0, 255), 2)

# resize trees
trees = cv2.resize(trees,(w,h),0,0)

# generate result
result = img.copy()
result[y:y+h, x:x+w] = img[y:y+h, x:x+w]/255 * trees

# write result to disk
cv2.imwrite("substrate_over_trees.jpg", result)

cv2.imshow("ALPHA", alpha)
cv2.imshow("IMG", img)
cv2.imshow("THRESH", thresh)
cv2.imshow("TREES", trees)
cv2.imshow("RESULT", result)
cv2.waitKey(0)
cv2.destroyAllWindows()


Result:

enter image description here

Note that there is distortion of the trees image, because its aspect ratio does not match the region of the substrate image corresponding to the contour bounding box. This can be changed to maintain the aspect ratio, but then the image will need to be padded to white or some other color to fill the remaining area of the bounding box.

fmw42
  • 46,825
  • 10
  • 62
  • 80