2013-02-08 46 views
3

我正在Python上编程类,我们正在通过定义镜像点,然后使用嵌套for循环将一个像素从一侧复制到另一侧来处理镜像。例如,垂直镜像图像将使用下面的代码:对角线在Python中的镜像图像

def mirrorVertical(source): 
mirrorPoint = getWidth(source)/2 
width = getWidth(source) 
for y in range(0,getHeight(source)): 
    for x in range(0,mirrorPoint): 
    leftPixel = getPixel(source,x,y) 
    rightPixel = getPixel(source,width - x - 1,y) 
    color = getColor(leftPixel) 
    setColor(rightPixel,color) 

我目前工作的一个分配问题,问我们,以便左上方被反射到右下方对角镜上的图像。我迄今发现的每个示例和答案都只适用于方形图像,我需要能够将其应用于任何图像,最好是通过定义对角镜像点。我一直在尝试使用y = mx + b样式方程来定义镜像点,但是我无法弄清楚如何告诉Python做出这样的结论。任何不具体的方形图像帮助将不胜感激!

注意:由于我是全新的,因此我无法发布图像,但对角镜像点将从左下角运行到右上角。左上角三角形的图像将反映在右下角。

回答

0

我假设你想要根据45度线而不是矩形对角线进行镜像。

您必须创建一个新图像,它的宽度是原始高度,高度是原始宽度。

如果坐标系的原点位于左下角,则将原点中的点(x,y)复制到新图像中的(y,x)位置。如果它是另一个角落,你必须要考虑多一点;)

3

您可以把左上角有一个像这样的非方阵的右下:

height = getHeight(source) 
width = getWidth(source) 
for i in range(height - 1): 
    for j in range(int(width * float(height - i)/height)): 
     # Swap pixel i,j with j,i 

这适用于沿对角线镜像。你似乎暗示你可能想要沿着某个任意位置进行镜像。在这种情况下,您需要决定如何填充镜像线另一侧没有匹配像素的像素。

你提到你正在做一个任务,所以你可能需要明确地做循环,但是请注意,如果你把你的数据放到一个numpy数组中,你可以很容易地(并且更高效地)实现你想要的组合的numpy功能fliplr,flipudtranspose

另请注意,在您的代码示例中(镜像左/右),您正在将左侧像素复制到右侧,但反之亦然,因此您实际上并不是镜像映像。

2

只是分享对角镜像的一种方式,左下到右上

学生负责相适应​​,如果他需要从“右上至左下镜像“或使用相反的对角线。

# !! Works only with squared pictures... !! 
def diagMirrorPicture(picture): 
    height = getHeight(picture) 
    width = getWidth(picture) 

    if (height != width): 
     printNow("Error: The input image is not squared. Found [" + \ 
            str(width) + " x " + str(height) + "] !") 
     return None 

    newPicture = makeEmptyPicture(width, height) 

    mirrorPt = 0 
    for x in range(0, width, 1): 
     for y in range(mirrorPt, height, 1): 
      sourcePixel = getPixel(picture, x, y) 
      color = getColor(sourcePixel) 

      # Copy bottom-left as is 
      targetPixel = getPixel(newPicture, x, y) 
      setColor(targetPixel, color) 

      # Mirror bottom-left to top right 
      targetPixel = getPixel(newPicture, y, x) 
      #         ^^^^ (simply invert x and y) 
      setColor(targetPixel, color) 

     # Here we shift the mirror point 
     mirrorPt += 1 

    return newPicture 


file = pickAFile() 
picture = makePicture(file) 

picture = diagMirrorPicture(picture) 

if (picture): 
    writePictureTo(picture, "/home/mirror-diag2.png") 
    show(picture) 

注:这表现为,如果我们操作的垂直镜,用于独立地每条像素线,沿着垂直轴通过由mirrorPt点。


输出(绘画由安东尼·塔皮埃斯):


................. enter image description here ... .............. enter image description here ..................






以下是实验性只是为了好玩...

# Draw point, with check if the point is in the image area 
def drawPoint(pic, col, x, y): 
    if (x >= 0) and (x < getWidth(pic)) and (y >= 0) and (y < getHeight(pic)): 
    px = getPixel(pic, x, y) 
    setColor(px, col) 

# Draw line segment given two points 
# From Bresenham's line algorithm : 
# http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm 
def drawLine(pic, col, x0, y0, x1, y1): 

    dx = abs(x1-x0) 
    dy = abs(y1-y0) 
    sx = sy = 0 

    #sx = 1 if x0 < x1 else -1 
    #sy = 1 if y0 < y1 else -1 

    if (x0 < x1): 
    sx = 1 
    else: 
    sx = -1 
    if (y0 < y1): 
    sy = 1 
    else: 
    sy = -1 

    err = dx - dy 

    while (True): 

    drawPoint(pic, col, x0, y0) 

    if (x0 == x1) and (y0 == y1): 
     break 

    e2 = 2 * err 
    if (e2 > -dy): 
     err = err - dy 
     x0 = x0 + sx 

    if (x0 == x1) and (y0 == y1): 
     drawPoint(pic, col, x0, y0) 
     break 

    if (e2 < dx): 
     err = err + dx 
     y0 = y0 + sy 


# Works only with squared cropped areas : 
# i.e. in [(x0, y0), (x1, y1)], abs(x1-x0) must be equal to abs(y1-y0) 
# 
# USAGE : 
# * To get bottom reflected to top use x0 > x1 
# * To get top reflected to bottom use x0 < x1 

def diagCropAndMirrorPicture(pic, startPt, endPt): 
    w = getWidth(pic) 
    h = getHeight(pic) 

    if (startPt[0] < 0) or (startPt[0] >= w) or \ 
     (startPt[1] < 0) or (startPt[1] >= h) or \ 
     (endPt[0] < 0) or (endPt[0] >= w) or \ 
     (endPt[1] < 0) or (endPt[1] >= h): 
      printNow("Error: The input points must be in the image range !") 
      return None 

    new_w = abs(startPt[0] - endPt[0]) 
    new_h = abs(startPt[1] - endPt[1]) 

    if (new_w != new_h): 
      printNow("Error: The input points do not form a square !") 
      return None 

    printNow("Given: (" + str(startPt[0]) + ", " + str(endPt[0]) + ") and (" \ 
         + str(startPt[1]) + ", " + str(endPt[1]) + ")") 

    newPicture = makeEmptyPicture(new_w, new_h) 

    if (startPt[0] < endPt[0]): 
     offsetX = startPt[0] 
     switchX = False 
     switchTB = True 
    else: 
     offsetX = endPt[0] 
     switchX = True 
     switchTB = False 

    if (startPt[1] < endPt[1]): 
     offsetY = startPt[1] 
     switchY = False 
    else: 
     offsetY = endPt[1] 
     switchY = True 

    # (switchX XOR switchY) 
    changeDiag = (switchX != switchY) 

    mirror_pt = 0 
    for x in range(0, new_w, 1): 

     for y in range(mirror_pt, new_h, 1): 
     #for y in range(0, new_h, 1): 

      oldX = x 
      oldY = y 


      if (switchTB): 
       sourcePixel = getPixel(picture, offsetX+new_w-1- oldX, offsetY+new_h-1- oldY) 
      else: 
       sourcePixel = getPixel(picture, offsetX+oldX, offsetY+oldY) 
      color = getColor(sourcePixel) 

      if (changeDiag): 
       newX = new_w-1 - x 
       newY = new_h-1 - y 
       #printNow("Change Diag !") 
      else: 
       newX = x 
       newY = y 

      # Copied half 
      if (switchTB): 
       targetPixel = getPixel(newPicture, new_w-1- x, new_h-1- y) 
      else: 
       targetPixel = getPixel(newPicture, x, y) 
      setColor(targetPixel, color) 

      # Mirror half (simply invert x and y) 
      if (switchTB): 
       targetPixel = getPixel(newPicture, new_h-1- newY, new_w-1- newX) 
      else: 
       targetPixel = getPixel(newPicture, newY, newX) 
      setColor(targetPixel, color) 


     # Here we shift the mirror point 
     if (not changeDiag): 
      mirror_pt += 1 


    return newPicture 


file = pickAFile() 
pic = makePicture(file) 
picture = makePicture(file) 

# Draw working area 
drawLine(pic, white, 30, 60, 150, 180) 
drawLine(pic, white, 30, 180, 150, 60) 
drawLine(pic, black, 30, 60, 30, 180) 
drawLine(pic, black, 30, 60, 150, 60) 
drawLine(pic, black, 150, 60, 150, 180) 
drawLine(pic, black, 30, 180, 150, 180) 
show(pic) 
writePictureTo(pic, "D:\\pic.png") 

# Build cropped and mirrored areas 
pic1 = diagCropAndMirrorPicture(picture, (150, 60), (30, 180)) 
pic2 = diagCropAndMirrorPicture(picture, (30, 180), (150, 60)) 
pic3 = diagCropAndMirrorPicture(picture, (150, 180), (30, 60)) 
pic4 = diagCropAndMirrorPicture(picture, (30, 60), (150, 180)) 

# Show cropped and mirrored areas 
if (pic1): 
    writePictureTo(pic1, "D:\\pic1.png") 
    show(pic1) 

if (pic2): 
    writePictureTo(pic2, "D:\\pic2.png") 
    show(pic2) 

if (pic3): 
    writePictureTo(pic3, "D:\\pic3.png") 
    show(pic3) 

if (pic4): 
    writePictureTo(pic4, "D:\\pic4.png") 
    show(pic4) 




........ ....................... ....................... enter image description here .......................... ............................


....... enter image description here ..... ..... enter image description here .......... enter image description here .......... enter image description here .......



+1

嘿,你! ;)很高兴你喜欢它。我正在将我最近发布的答案链接分组,以便向您发送电子邮件......但您已经找到了它们...... – 2013-06-29 13:11:24

+1

好吧,我会用法语给您写信! – 2013-06-29 13:13:58

+0

它应该。你确定你正在使用完全“平方”的图片作为输入吗?你得到的错误是什么?我添加了一张支票来拒绝非平方的照片。干杯。 – 2013-06-30 20:11:17