使用Python的OpenCV,如何处理图像而不损失质量

huangapple go评论113阅读模式
英文:

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.

  1. import cv2 as cv
  2. import numpy as np
  3. img = cv.imread('tekapo.bmp')
  4. if img is None:
  5. print("file not found")
  6. rows, cols, ch = img.shape
  7. #초기 x, y값 및 기본값 설정
  8. c = (int(cols/2), int(rows/2))
  9. def draw_line(input_img): #input_img에 선, 원 그리고 변형된 이미지 반환
  10. (x, y) = c
  11. c_img = input_img.copy()
  12. cv.line(c_img, c, (640, y), (0, 0, 255), 1) #x축 보조선
  13. cv.line(c_img, c, (x, 480), (0, 255, 0), 1) #y축 보조선
  14. cv.circle(c_img, c, 5, (0, 0, 255), -1)
  15. return c_img
  16. def imshow(input_img): #input_img에 point그리고 출력, input_img는 변형 X
  17. c_img = input_img.copy()
  18. cv.imshow('C_img', draw_line(c_img))
  19. def click_mouse(e, x, y, d, p):
  20. if e == cv.EVENT_LBUTTONDOWN:
  21. global c
  22. c = (int(x), int(y)) #좌표 저장
  23. imshow(copy_img)
  24. def translate(input_img, dx, dy):
  25. rows, cols, ch = input_img.shape
  26. M = np.float32([[1, 0, dx], [0, 1, dy]])
  27. c_img = input_img.copy()
  28. c_img2 = cv.warpAffine(c_img, M, (cols, rows))
  29. img = c_img2.copy()
  30. imshow(c_img2)
  31. return img
  32. copy_img = img.copy() #변형시킬 이미지가 담길 변수
  33. imshow(copy_img)
  34. cv.setMouseCallback('C_img', click_mouse, copy_img)
  35. while True:
  36. key = cv.waitKey()
  37. if key == ord('t'):#오른쪽 아래로 가는 기능
  38. copy_img = translate(copy_img, 5, 5)
  39. elif key == ord('e'):#왼쪽 위로 가는 기능
  40. copy_img = translate(copy_img, -5, -5)
  41. elif key == 27:
  42. print(c)
  43. break
  44. 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

    1. M = np.float64([[1, 0, 0],
    2. [0, 1, 0]])
  • 不使用 translate,实现一个更新矩阵 M 的方法。
    M 通过改变平移和当前的 M 来更新。
    更改是通过左侧乘以平移矩阵来应用的,如我[之前的回答][1]中所描述:

    1. def translate_mat(M, dx, dy):
    2. # 而不是更新图像,更新变换矩阵 M
    3. T0 = np.vstack((M, np.array([0, 0, 1]))) # 在 M 底部添加行 [0, 0, 1]([0, 0, 1] 应用于眼矩阵的最后一行),T0 是 3x3 矩阵。
    4. # 平移矩阵(3x3)
    5. T1 = np.float64([[1, 0, dx],
    6. [0, 1, dy],
    7. [0, 0, 1 ]])
    8. T = T1 @ T0 # 链式变换(将平移矩阵 T1 与输入平移矩阵相乘)。
    9. M = T[0:2, :] # 从 T 中删除最后一行(仿射变换的最后一行始终为 [0, 0, 1],OpenCV 转换会省略最后一行)。
    10. return M # 返回更新后的 M(应用平移于输入 M 后的 M)。
  • 在 while 循环中,更新 M 并将 warpAffine 应用于 img(而不是更新 copy_img):

    1. while True:
    2. key = cv.waitKey()
    3. if key == ord('t'): # 向右下移动功能
    4. # copy_img = translate(copy_img, 5, 5)
    5. M = translate_mat(M, 5, 5) # 将变换应用于变换矩阵 M,而不是修改图像。
    6. copy_img = cv.warpAffine(img, M, (cols, rows)) # 对原始图像应用变换
    7. imshow(copy_img)

代码示例:

  1. import cv2 as cv
  2. import numpy as np
  3. img = cv.imread('tekapo.bmp')
  4. if img is None:
  5. print("文件未找到")
  6. rows, cols, ch = img.shape
  7. # 初始化 x、y 值和默认值
  8. c = (int(cols/2), int(rows/2))
  9. def draw_line(input_img): # 在 input_img 上绘制线条、圆并返回转换后的图像
  10. (x, y) = c
  11. c_img = input_img.copy()
  12. cv.line(c_img, c, (640, y), (0, 0, 255), 1) # x 轴辅助线
  13. cv.line(c_img, c, (x, 480), (0, 255, 0), 1) # y 轴辅助线
  14. cv.circle(c_img, c, 5, (0, 0, 255), -1)
  15. return c_img
  16. def imshow(input_img): # 在 input_img 上显示点并输出,input_img 未经变换
  17. c_img = input_img.copy()
  18. cv.imshow('C_img', draw_line(c_img))
  19. def click_mouse(e, x, y, d, p):
  20. if e == cv.EVENT_LBUTTONDOWN:
  21. global c
  22. c = (int(x), int(y)) # 保存坐标
  23. imshow(copy_img)
  24. # def translate(input_img, dx, dy):
  25. # rows, cols, ch = input_img.shape
  26. # M = np.float32([[1, 0, dx], [0, 1, dy]])
  27. # c_img = input_img.copy()
  28. # c_img2 = cv.warpAffine(c_img, M, (cols, rows))
  29. # img = c_img2.copy()
  30. # imshow(c_img2)
  31. # return img
  32. def translate_mat(M, dx, dy):
  33. # 而不是更新图像,更新平移矩阵 M
  34. T0 = np.vstack((M, np.array([0, 0, 1]))) # 在 M 底部添加行 [0, 0, 1]([0, 0, 1] 应用于眼矩阵的最后一行),T0 是 3x3 矩阵。
  35. # 平移矩阵(3x3)
  36. T1 = np.float64([[1, 0, dx],
  37. [0, 1, dy],
  38. [0, 0, 1 ]])
  39. T = T1 @ T0 # 链式变换(将平移矩阵 T1 与输入平移矩阵相乘)。
  40. M = T[0:2, :] # 从 T 中删除最后一行(仿射变换的最后一行始终为 [0, 0, 1],OpenCV 转换会省略最后一行)。
  41. return M # 返回更新后的 M(应用平移于输入 M 后的 M).
  42. copy_img = img.copy() # 存储要变换的图像的变量
  43. imshow(copy_img)
  44. cv.setMouseCallback('C_img', click_mouse, copy_img)
  45. # 使用“eye”变换初始化 M(去除第三行)。
  46. M = np.float64([[1, 0, 0],
  47. [0, 1, 0]])
  48. rows, cols, ch = img.shape
  49. while True:
  50. key = cv.waitKey()
  51. if key == ord('t'): # 向右下移动功能
  52. # copy_img = translate(copy_img, 5, 5)
  53. M = translate_mat(M, 5, 5) # 将变换应用于变换矩阵 M,而不是修改图像。
  54. copy_img = cv.w
  55. <details>
  56. <summary>英文:</summary>
  57. Instead of updating the image, we may update the transformation matrix `M`, and apply `warpAffine` to the original image.
  58. That way we are preserving the original image and only modifying the transformation matrix each time the relevant key is pressed.
  59. ---
  60. - Initialize matrix `M` with &quot;eye&quot; transformation (without the third row):
  61. M = np.float64([[1, 0, 0],
  62. [0, 1, 0]])
  63. - Instead of using `translate`, implement a method that updates matrix `M`.
  64. `M` is updated by changing the translation and the current `M`.
  65. Changing is applied by multiplying the translation matrix from the left, as described in my [previous answer][1]:
  66. def translate_mat(M, dx, dy):
  67. # Instead of updating the image, update the transformation matrix M
  68. 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.
  69. # Translation matrix (3x3)
  70. T1 = np.float64([[1, 0, dx],
  71. [0, 1, dy],
  72. [0, 0, 1 ]])
  73. T = T1 @ T0 # Chain transformations (multiply translation matrix T1 by the input translation matrix).
  74. 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).
  75. return M # Return updated M (after applying the translation on the input M).
  76. - In the while loop, update `M` and apply `warpAffine` to `img` (instead of updating `copy_img`):
  77. while True:
  78. key = cv.waitKey()
  79. if key == ord(&#39;t&#39;):#오른쪽 아래로 가는 기능
  80. # copy_img = translate(copy_img, 5, 5)
  81. M = translate_mat(M, 5, 5) # Apply transformation to transformation matrix M instead of modifying the image.
  82. copy_img = cv.warpAffine(img, M, (cols, rows)) # Apply warp to the original image
  83. imshow(copy_img)
  84. ---
  85. Code sample:
  86. import cv2 as cv
  87. import numpy as np
  88. img = cv.imread(&#39;tekapo.bmp&#39;)
  89. if img is None:
  90. print(&quot;file not found&quot;)
  91. rows, cols, ch = img.shape
  92. #초기 x, y값 및 기본값 설정
  93. c = (int(cols/2), int(rows/2))
  94. def draw_line(input_img): #input_img에 선, 원 그리고 변형된 이미지 반환
  95. (x, y) = c
  96. c_img = input_img.copy()
  97. cv.line(c_img, c, (640, y), (0, 0, 255), 1) #x축 보조선
  98. cv.line(c_img, c, (x, 480), (0, 255, 0), 1) #y축 보조선
  99. cv.circle(c_img, c, 5, (0, 0, 255), -1)
  100. return c_img
  101. def imshow(input_img): #input_img에 point그리고 출력, input_img는 변형 X
  102. c_img = input_img.copy()
  103. cv.imshow(&#39;C_img&#39;, draw_line(c_img))
  104. def click_mouse(e, x, y, d, p):
  105. if e == cv.EVENT_LBUTTONDOWN:
  106. global c
  107. c = (int(x), int(y)) #좌표 저장
  108. imshow(copy_img)
  109. #def translate(input_img, dx, dy):
  110. # rows, cols, ch = input_img.shape
  111. # M = np.float32([[1, 0, dx], [0, 1, dy]])
  112. # c_img = input_img.copy()
  113. # c_img2 = cv.warpAffine(c_img, M, (cols, rows))
  114. # img = c_img2.copy()
  115. # imshow(c_img2)
  116. # return img
  117. def translate_mat(M, dx, dy):
  118. # Instead of uprating the image, update the translation matrix M
  119. 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.
  120. # Translation matrix (3x3)
  121. T1 = np.float64([[1, 0, dx],
  122. [0, 1, dy],
  123. [0, 0, 1 ]])
  124. T = T1 @ T0 # Chain transformations (multiply translation matrix T1 by the input translation matrix).
  125. 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).
  126. return M # Return updated M (after applying the translation on the input M).
  127. copy_img = img.copy() #변형시킬 이미지가 담길 변수
  128. imshow(copy_img)
  129. cv.setMouseCallback(&#39;C_img&#39;, click_mouse, copy_img)
  130. # Initialize M to &quot;eye&quot; transformation (without the third row).
  131. M = np.float64([[1, 0, 0],
  132. [0, 1, 0]])
  133. rows, cols, ch = img.shape
  134. while True:
  135. key = cv.waitKey()
  136. if key == ord(&#39;t&#39;):#오른쪽 아래로 가는 기능
  137. # copy_img = translate(copy_img, 5, 5)
  138. M = translate_mat(M, 5, 5) # Apply transformation to transformation matrix M instead of modifying the image.
  139. copy_img = cv.warpAffine(img, M, (cols, rows)) # Apply warp to the original image
  140. imshow(copy_img)
  141. elif key == ord(&#39;e&#39;):#왼쪽 위로 가는 기능
  142. # copy_img = translate(copy_img, -5, -5)
  143. M = translate_mat(M, -5, -5) # Apply transformation to transformation matrix M instead of modifying the image.
  144. copy_img = cv.warpAffine(img, M, (cols, rows)) # Apply warp to the original image
  145. imshow(copy_img)
  146. elif key == 27:
  147. print(c)
  148. break
  149. cv.destroyAllWindows()
  150. ---
  151. Sample image after pressing `&#39;t&#39;` 10 times:
  152. [![enter image description here][2]][2]
  153. Sample image after pressing `&#39;t&#39;` 10 times and then pressing `&#39;e&#39;` 20 times:
  154. [![enter image description here][3]][3]
  155. [1]: https://stackoverflow.com/a/75391691/4926757
  156. [2]: https://i.stack.imgur.com/Pav7o.png
  157. [3]: https://i.stack.imgur.com/1DXMP.png
  158. </details>

huangapple
  • 本文由 发表于 2023年4月11日 00:43:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/75978933.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定