当前位置: 首页 > 知识库问答 >
问题:

在openCV中以特定坐标在另一图像上显示图像

郜谦
2023-03-14

我试图在一个特定的坐标上显示一个图像在另一个图像上。我已经使用网络摄像头检测到aruco标记,我想在aruco标记上显示另一张图像。aruco标记可以移动,覆盖图像应该随着标记移动。

有各种绘图功能和将文本输入到图像中。我尝试过图像叠加和图像单应性。

我可以得到拐角的坐标。有没有在这些坐标处插入图像的功能?

import cv2
import cv2.aruco as aruco
import glob

markerLength = 0.25

cap = cv2.VideoCapture(0)

criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)

objp = np.zeros((6*7,3), np.float32)
objp[:,:2] = np.mgrid[0:7,0:6].T.reshape(-1,2)

objpoints = [] 
imgpoints = []

images = glob.glob('calib_images/*.jpg')

for fname in images:
    img = cv2.imread(fname)
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

    ret, corners = cv2.findChessboardCorners(gray, (7,6),None)

    if ret == True:
        objpoints.append(objp)

        corners2 = cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria)
        imgpoints.append(corners2)
        img = cv2.drawChessboardCorners(img, (7,6), corners2,ret)


ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1],None,None)

calibrationFile = "calibrationFileName.xml"
calibrationParams = cv2.FileStorage(calibrationFile, cv2.FILE_STORAGE_READ) 
camera_matrix = calibrationParams.getNode("cameraMatrix").mat() 
dist_coeffs = calibrationParams.getNode("distCoeffs").mat() 

while(True):
    ret, frame = cap.read()

    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    aruco_dict = aruco.Dictionary_get(aruco.DICT_6X6_250)
    arucoParameters =  aruco.DetectorParameters_create()

    corners, ids, rejectedImgPoints = aruco.detectMarkers(gray, aruco_dict, parameters=arucoParameters)
    if np.all(ids != None):
        rvec, tvec, _ = aruco.estimatePoseSingleMarkers(corners, markerLength, mtx, dist) 
        axis = aruco.drawAxis(frame, mtx, dist, rvec, tvec, 0.3) 
        print(ids)
        display = aruco.drawDetectedMarkers(axis, corners)
        display = np.array(display)
    else:
        display = frame

    cv2.imshow('Display',display)
    if cv2.waitKey(1) & 0xFF == ord('q'):
            break

cap.release()
cv2.destroyAllWindows()```

共有3个答案

孙梓
2023-03-14

事实上,我发现图像单应性可以用来做这件事。这是更新后的代码。

import numpy as np
import cv2
import cv2.aruco as aruco

cap = cv2.VideoCapture(0)

while(True):
    ret, frame = cap.read()

    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    aruco_dict = aruco.Dictionary_get(aruco.DICT_6X6_250)
    arucoParameters =  aruco.DetectorParameters_create()

    corners, ids, rejectedImgPoints = aruco.detectMarkers(gray, aruco_dict, parameters=arucoParameters)
    if np.all(ids != None):
        display = aruco.drawDetectedMarkers(frame, corners)
        x1 = (corners[0][0][0][0], corners[0][0][0][1]) 
        x2 = (corners[0][0][1][0], corners[0][0][1][1]) 
        x3 = (corners[0][0][2][0], corners[0][0][2][1]) 
        x4 = (corners[0][0][3][0], corners[0][0][3][1])  

        im_dst = frame 
        im_src = cv2.imread("mask.jpg")
        size = im_src.shape
        pts_dst = np.array([x1,x2,x3,x4])
        pts_src = np.array(
                       [
                        [0,0],
                        [size[1] - 1, 0],
                        [size[1] - 1, size[0] -1],
                        [0, size[0] - 1 ]
                        ],dtype=float
                       );


        h, status = cv2.findHomography(pts_src, pts_dst)
        temp = cv2.warpPerspective(im_src, h, (im_dst.shape[1],im_dst.shape[0])) 
        cv2.fillConvexPoly(im_dst, pts_dst.astype(int), 0, 16);
        im_dst = im_dst + temp  
        cv2.imshow('Display',im_dst) 
    else:
        display = frame
        cv2.imshow('Display',display)
    if cv2.waitKey(1) & 0xFF == ord('q'):
            break

cap.release()
cv2.destroyAllWindows()
皇甫雨华
2023-03-14

@user8190410的答案很好用。为了给出一个完整的答案,为了在特定位置对两个不同大小的图像进行alpha混合,您可以执行以下操作:

alpha= 0.7
img1_mod = img1.copy()
img1_mod[:pos_x,:pos_y,:] = img1[:pos_x,:pos_y,:]*alpha + img2*(1-alpha)
cv2.imshow('Image1Mod', img1_mod)
崔高远
2023-03-14

替换图像的一部分

import cv2
import numpy as np

img1 = cv2.imread('Desert.jpg')
img2 = cv2.imread('Penguins.jpg')

img3 = img1.copy()
# replace values at coordinates (100, 100) to (399, 399) of img3 with region of img2
img3[100:400,100:400,:] = img2[100:400,100:400,:]
cv2.imshow('Result1', img3)

混合两个图像

alpha = 0.5
img3 = np.uint8(img1*alpha + img2*(1-alpha))
cv2.imshow('Result2', img3)
 类似资料:
  • 我试图从docker容器中使用OpenCV imshow GUI。我使用nvidia-docker启动容器,因为该容器包含GPU版本的Tensorflow 我试图显示的图像是使用MatplotLib显示的。我该如何纠正这一点呢?谢谢

  • 它将我带到图库以选择图像,但未显示在应用程序中,当单击上传按钮时,它只是一个空白图像视图 < li >我的Java代码 < li>XML代码 运行时显示此错误 java.lang.IllegalArgumentException:uri不能为空 以下两处给出错误的行显示了uri错误

  • 我正在尝试做一个小应用程序,只显示图片从一个特定的文件夹在一个图库视图。我找到了几个例子,但每一个都只能显示一个图像。我将在下面发布的这个例子是一个很好的帮助,它做几乎完全是我想要它做的,我只需要改变它显示图像从特定的文件夹,而不是所有的文件夹。我花了几天的时间来尝试,但我似乎没有添加正确的代码。我觉得这是一件很简单的事情,我也错过了。如有任何帮助,我们将不胜感激!

  • 我尝试了一切,但图像不会显示,我试图缩小图像,但没有用,我试图改变路径,我试图更改图像的位置,但没有帮助,我试图在互联网上搜索,但什么都没有。 我看到的只是空白的图形用户界面,没有文本和图像。如果你能帮我,你会帮我一个大忙。 代码如下:

  • 问题内容: 在JPanel上显示jpg图像(从本地文件夹加载)的最合适的图像类型是什么? 干杯。 问题答案:

  • 我想显示图像,但不知道该怎么做。我不知道是必须安装一些库文件,还是简单地安装就可以了。实际上我想做图像处理,但首先我必须接受图像输入并显示图像,然后我可以得到图像处理的效果作为输出,并决定它(算法)是否正确。我只安装了eclipse。我也在谷歌上搜索过,但是无论他们建议什么都不管用。要么我得装点什么,要么不装。 我已经尝试了以下代码: 它只是显示一个图形窗口,但不能显示图像“bishnu.jpg”