英文:
with python openCV, how can i process image without loss
问题
Sure, here is the translated content of your text, excluding the code:
"我想制作一个具有多个功能(平移、旋转、翻转、剪切等)的程序,但在实现平移功能时遇到了问题。当我将图像向左移动然后向右移动时,图像的左侧部分丢失了。我认为这个问题在应用其他功能时也会出现相同的情况。
我希望在处理图像时不会丢失部分内容。
我从这里的链接中看到了类似的问题 链接,但我认为那似乎与我的情况有些不同。"
英文:
i want to make program that has several functions(translate, rotate, flip,shear..)
but i got problem with implemening the translating function.
when i move image left and then right, left part of the image is lost.
and i think this problem will be same with other functions.
import cv2 as cv
import numpy as np
img = cv.imread('tekapo.bmp')
if img is None:
print("file not found")
rows, cols, ch = img.shape
#초기 x, y값 및 기본값 설정
c = (int(cols/2), int(rows/2))
def draw_line(input_img): #input_img에 선, 원 그리고 변형된 이미지 반환
(x, y) = c
c_img = input_img.copy()
cv.line(c_img, c, (640, y), (0, 0, 255), 1) #x축 보조선
cv.line(c_img, c, (x, 480), (0, 255, 0), 1) #y축 보조선
cv.circle(c_img, c, 5, (0, 0, 255), -1)
return c_img
def imshow(input_img): #input_img에 point그리고 출력, input_img는 변형 X
c_img = input_img.copy()
cv.imshow('C_img', draw_line(c_img))
def click_mouse(e, x, y, d, p):
if e == cv.EVENT_LBUTTONDOWN:
global c
c = (int(x), int(y)) #좌표 저장
imshow(copy_img)
def translate(input_img, dx, dy):
rows, cols, ch = input_img.shape
M = np.float32([[1, 0, dx], [0, 1, dy]])
c_img = input_img.copy()
c_img2 = cv.warpAffine(c_img, M, (cols, rows))
img = c_img2.copy()
imshow(c_img2)
return img
copy_img = img.copy() #변형시킬 이미지가 담길 변수
imshow(copy_img)
cv.setMouseCallback('C_img', click_mouse, copy_img)
while True:
key = cv.waitKey()
if key == ord('t'):#오른쪽 아래로 가는 기능
copy_img = translate(copy_img, 5, 5)
elif key == ord('e'):#왼쪽 위로 가는 기능
copy_img = translate(copy_img, -5, -5)
elif key == 27:
print(c)
break
cv.destroyAllWindows()
i've saw similar problem from here link
but i think that looks little different situation with mine.
i want to process image without losing part of it
答案1
得分: 1
以下是您要翻译的内容:
- 替代更新图像,我们可以更新变换矩阵
M
并将warpAffine
应用于原始图像。这样我们保留了原始图像,只在按相关按键时每次修改变换矩阵。
-
使用“eye”变换(去除第三行)初始化矩阵
M
:M = np.float64([[1, 0, 0], [0, 1, 0]])
-
不使用
translate
,实现一个更新矩阵M
的方法。
M
通过改变平移和当前的M
来更新。
更改是通过左侧乘以平移矩阵来应用的,如我[之前的回答][1]中所描述:def translate_mat(M, dx, dy): # 而不是更新图像,更新变换矩阵 M T0 = np.vstack((M, np.array([0, 0, 1]))) # 在 M 底部添加行 [0, 0, 1]([0, 0, 1] 应用于眼矩阵的最后一行),T0 是 3x3 矩阵。 # 平移矩阵(3x3) T1 = np.float64([[1, 0, dx], [0, 1, dy], [0, 0, 1 ]]) T = T1 @ T0 # 链式变换(将平移矩阵 T1 与输入平移矩阵相乘)。 M = T[0:2, :] # 从 T 中删除最后一行(仿射变换的最后一行始终为 [0, 0, 1],OpenCV 转换会省略最后一行)。 return M # 返回更新后的 M(应用平移于输入 M 后的 M)。
-
在 while 循环中,更新
M
并将warpAffine
应用于img
(而不是更新copy_img
):while True: key = cv.waitKey() if key == ord('t'): # 向右下移动功能 # copy_img = translate(copy_img, 5, 5) M = translate_mat(M, 5, 5) # 将变换应用于变换矩阵 M,而不是修改图像。 copy_img = cv.warpAffine(img, M, (cols, rows)) # 对原始图像应用变换 imshow(copy_img)
代码示例:
import cv2 as cv
import numpy as np
img = cv.imread('tekapo.bmp')
if img is None:
print("文件未找到")
rows, cols, ch = img.shape
# 初始化 x、y 值和默认值
c = (int(cols/2), int(rows/2))
def draw_line(input_img): # 在 input_img 上绘制线条、圆并返回转换后的图像
(x, y) = c
c_img = input_img.copy()
cv.line(c_img, c, (640, y), (0, 0, 255), 1) # x 轴辅助线
cv.line(c_img, c, (x, 480), (0, 255, 0), 1) # y 轴辅助线
cv.circle(c_img, c, 5, (0, 0, 255), -1)
return c_img
def imshow(input_img): # 在 input_img 上显示点并输出,input_img 未经变换
c_img = input_img.copy()
cv.imshow('C_img', draw_line(c_img))
def click_mouse(e, x, y, d, p):
if e == cv.EVENT_LBUTTONDOWN:
global c
c = (int(x), int(y)) # 保存坐标
imshow(copy_img)
# def translate(input_img, dx, dy):
# rows, cols, ch = input_img.shape
# M = np.float32([[1, 0, dx], [0, 1, dy]])
# c_img = input_img.copy()
# c_img2 = cv.warpAffine(c_img, M, (cols, rows))
# img = c_img2.copy()
# imshow(c_img2)
# return img
def translate_mat(M, dx, dy):
# 而不是更新图像,更新平移矩阵 M
T0 = np.vstack((M, np.array([0, 0, 1]))) # 在 M 底部添加行 [0, 0, 1]([0, 0, 1] 应用于眼矩阵的最后一行),T0 是 3x3 矩阵。
# 平移矩阵(3x3)
T1 = np.float64([[1, 0, dx],
[0, 1, dy],
[0, 0, 1 ]])
T = T1 @ T0 # 链式变换(将平移矩阵 T1 与输入平移矩阵相乘)。
M = T[0:2, :] # 从 T 中删除最后一行(仿射变换的最后一行始终为 [0, 0, 1],OpenCV 转换会省略最后一行)。
return M # 返回更新后的 M(应用平移于输入 M 后的 M).
copy_img = img.copy() # 存储要变换的图像的变量
imshow(copy_img)
cv.setMouseCallback('C_img', click_mouse, copy_img)
# 使用“eye”变换初始化 M(去除第三行)。
M = np.float64([[1, 0, 0],
[0, 1, 0]])
rows, cols, ch = img.shape
while True:
key = cv.waitKey()
if key == ord('t'): # 向右下移动功能
# copy_img = translate(copy_img, 5, 5)
M = translate_mat(M, 5, 5) # 将变换应用于变换矩阵 M,而不是修改图像。
copy_img = cv.w
<details>
<summary>英文:</summary>
Instead of updating the image, we may update the transformation matrix `M`, and apply `warpAffine` to the original image.
That way we are preserving the original image and only modifying the transformation matrix each time the relevant key is pressed.
---
- Initialize matrix `M` with "eye" transformation (without the third row):
M = np.float64([[1, 0, 0],
[0, 1, 0]])
- Instead of using `translate`, implement a method that updates matrix `M`.
`M` is updated by changing the translation and the current `M`.
Changing is applied by multiplying the translation matrix from the left, as described in my [previous answer][1]:
def translate_mat(M, dx, dy):
# Instead of updating the image, update the transformation matrix M
T0 = np.vstack((M, np.array([0, 0, 1]))) # Add row [0, 0, 1] to the bottom of M ([0, 0, 1] applies last row of eye matrix), T0 is 3x3 matrix.
# Translation matrix (3x3)
T1 = np.float64([[1, 0, dx],
[0, 1, dy],
[0, 0, 1 ]])
T = T1 @ T0 # Chain transformations (multiply translation matrix T1 by the input translation matrix).
M = T[0:2, :] # Remove the last row from T (the last row of affine transformations is always [0, 0, 1] and OpenCV conversion is omitting the last row).
return M # Return updated M (after applying the translation on the input M).
- In the while loop, update `M` and apply `warpAffine` to `img` (instead of updating `copy_img`):
while True:
key = cv.waitKey()
if key == ord('t'):#오른쪽 아래로 가는 기능
# copy_img = translate(copy_img, 5, 5)
M = translate_mat(M, 5, 5) # Apply transformation to transformation matrix M instead of modifying the image.
copy_img = cv.warpAffine(img, M, (cols, rows)) # Apply warp to the original image
imshow(copy_img)
---
Code sample:
import cv2 as cv
import numpy as np
img = cv.imread('tekapo.bmp')
if img is None:
print("file not found")
rows, cols, ch = img.shape
#초기 x, y값 및 기본값 설정
c = (int(cols/2), int(rows/2))
def draw_line(input_img): #input_img에 선, 원 그리고 변형된 이미지 반환
(x, y) = c
c_img = input_img.copy()
cv.line(c_img, c, (640, y), (0, 0, 255), 1) #x축 보조선
cv.line(c_img, c, (x, 480), (0, 255, 0), 1) #y축 보조선
cv.circle(c_img, c, 5, (0, 0, 255), -1)
return c_img
def imshow(input_img): #input_img에 point그리고 출력, input_img는 변형 X
c_img = input_img.copy()
cv.imshow('C_img', draw_line(c_img))
def click_mouse(e, x, y, d, p):
if e == cv.EVENT_LBUTTONDOWN:
global c
c = (int(x), int(y)) #좌표 저장
imshow(copy_img)
#def translate(input_img, dx, dy):
# rows, cols, ch = input_img.shape
# M = np.float32([[1, 0, dx], [0, 1, dy]])
# c_img = input_img.copy()
# c_img2 = cv.warpAffine(c_img, M, (cols, rows))
# img = c_img2.copy()
# imshow(c_img2)
# return img
def translate_mat(M, dx, dy):
# Instead of uprating the image, update the translation matrix M
T0 = np.vstack((M, np.array([0, 0, 1]))) # Add row [0, 0, 1] to the bottom of M ([0, 0, 1] applies last row of eye matrix), T0 is 3x3 matrix.
# Translation matrix (3x3)
T1 = np.float64([[1, 0, dx],
[0, 1, dy],
[0, 0, 1 ]])
T = T1 @ T0 # Chain transformations (multiply translation matrix T1 by the input translation matrix).
M = T[0:2, :] # Remove the last row from T (the last row of affine transformations is always [0, 0, 1] and OpenCV conversion is omitting the last row).
return M # Return updated M (after applying the translation on the input M).
copy_img = img.copy() #변형시킬 이미지가 담길 변수
imshow(copy_img)
cv.setMouseCallback('C_img', click_mouse, copy_img)
# Initialize M to "eye" transformation (without the third row).
M = np.float64([[1, 0, 0],
[0, 1, 0]])
rows, cols, ch = img.shape
while True:
key = cv.waitKey()
if key == ord('t'):#오른쪽 아래로 가는 기능
# copy_img = translate(copy_img, 5, 5)
M = translate_mat(M, 5, 5) # Apply transformation to transformation matrix M instead of modifying the image.
copy_img = cv.warpAffine(img, M, (cols, rows)) # Apply warp to the original image
imshow(copy_img)
elif key == ord('e'):#왼쪽 위로 가는 기능
# copy_img = translate(copy_img, -5, -5)
M = translate_mat(M, -5, -5) # Apply transformation to transformation matrix M instead of modifying the image.
copy_img = cv.warpAffine(img, M, (cols, rows)) # Apply warp to the original image
imshow(copy_img)
elif key == 27:
print(c)
break
cv.destroyAllWindows()
---
Sample image after pressing `'t'` 10 times:
[![enter image description here][2]][2]
Sample image after pressing `'t'` 10 times and then pressing `'e'` 20 times:
[![enter image description here][3]][3]
[1]: https://stackoverflow.com/a/75391691/4926757
[2]: https://i.stack.imgur.com/Pav7o.png
[3]: https://i.stack.imgur.com/1DXMP.png
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论