运用python实现Cohen

您所在的位置:网站首页 使用编码裁剪算法的步骤 运用python实现Cohen

运用python实现Cohen

2024-07-17 06:55| 来源: 网络整理| 查看: 265

本篇为原创,仅仅作为学习参考之用,转载请说明。

一.题目描述:

在二维观察中,需要在观察坐标系下根据窗口大小对二维图形进行裁剪(clipping),只将位于窗口内的图形变换到视区输出。

直线段裁剪是二维图形裁剪的基础,裁剪的实质是判断直线段是否与窗口相交,如相交则进一步确定直线段上位于窗口内的部分。

那么怎么进行裁剪,首先要定义一下窗口内及窗口外的编码,每段直线的端点都被赋予一组四位二进制代码,

称为区域编码(region code,RC),用来标识直线段端点相对于窗口边界及其延长线的位置。如图

 

为了保证窗口内及窗口边界上直线段端点的编码为零,定义规则如下:

C0:若端点的xwxr,则C1=1,否则C1=0。

C2:若端点的ywyt,则C3=1,否则C3=0。

 

二.算法思路:

1.将直线起点p1和终点p2进行编码得到code1和code2.。

2.若两端点编码值均为0,说明直线段在窗口内,保留。

3.若两端点编码值code1&code2!=0,则说明直线段位于窗外的同一侧,或左方、或右方、或上方、或下方,抛弃。

4.若code1&code2==0,则直线段必然与窗口边界或窗口边界的延长线相交,此时该进行求交点操作。

任取编码值不为0的其中一点p1(该点必然在窗口外),然后用p1的编码值与窗口之外左右下上的编码值进行按位与&运算,

如果结果不为0,则直线段与窗口该侧的边界有交点,根据直线起点和终点求出交点。

将交点进行编码,把编码值赋给p1,则此时p1位于窗口边界上,即交点成为直线段起点,相当于舍去原来的p0与交点的那个线段,形成一个新的线段p1p2,

再次重复以上步骤,若皆在窗口中,则保留;否则继续循环,直到直线段全部位于窗口内为止。

 

 

三.注意事项

如果想绘制出图形的话要自己学习python的图形库哦,这里我用的是OpenCV库。首先建立画布,画出矩形窗口区域,然后才开始裁剪算法的,

这里裁剪的实质是判断直线的哪些部分在窗口内部,然后绘制出它们,窗口之外的部分就忽略。

 

四.代码

1 import numpy as np 2 import cv2 3 4 LEFT = 1 5 RIGHT = 2 6 BOTTOM = 4 7 TOP = 8 8 9 xl = 300 10 xr = 500 11 yb = 150 12 yt = 350 # 窗口的边界值 13 14 # Create a black image 15 img = np.zeros((500, 800, 3), np.uint8) # 相当于建立画布 16 17 18 # 编码 19 def encode(x, y): 20 c = 0 21 if x xr: 24 c = c | RIGHT 25 if y yt: 28 c = c | TOP 29 return c 30 31 32 # cohen-sutherland 算法 33 def CohenSutherland(x1, y1, x2, y2): 34 code1 = encode(x1, y1) 35 code2 = encode(x2, y2) 36 outcode = code1 # outcode是总在窗口外的那个端点 37 x, y = 0, 0 38 area = False # 设置一个是否满足条件的区分标志 39 while True: 40 if (code2 | code1) == 0: 41 area = True 42 break 43 if (code1 & code2) != 0: # 简弃之 44 break 45 if code1 == 0: # 开始求交点 46 outcode = code2 47 if (LEFT & outcode) != 0: # 与窗口左边界相交 48 x = xl 49 y = y1 + (y2 - y1) * (xl - x1) / (x2 - x1) 50 elif (RIGHT & outcode) != 0: 51 x = xr 52 y = y1 + (y2 - y1) * (xr - x1) / (x2 - x1) 53 elif (BOTTOM & outcode) != 0: 54 y = yb 55 x = x1 + (x2 - x1) * (yb - y1) / (y2 - y1) 56 elif (TOP & outcode) != 0: 57 y = yt 58 x = x1 + (x2 - x1) * (yt - y1) / (y2 - y1) 59 x = int(x) # 转换为整型 60 y = int(y) 61 if outcode == code1: 62 # print('hhh') # 测试用 63 x1 = x 64 y1 = y 65 code1 = encode(x, y) 66 else: 67 # print('eee') 68 x2 = x 69 y2 = y 70 code2 = encode(x, y) 71 if area == True: # 若满足条件即可划线 72 cv2.line(img, (x1, y1), (x2, y2), (0, 255, 255)) # 这里传递的点的坐标必须是整型,否则出错 73 return 74 75 76 # 做测试用的 不用理会 77 def test(): 78 print('test test test!') 79 c = encode(23, 46) 80 print(c) 81 82 83 def main(): # 主函数 84 # 绘制矩形窗口与直线 这里是显示裁剪之前的样子 要测试记得把下面的裁剪部分注释掉 85 cv2.rectangle(img, (300, 150), (500, 350), 255) 86 # cv2.line(img, (0, 0), (260, 260), (0, 255, 255)) 87 # cv2.line(img, (400, 50), (200, 400), (0, 255, 255)) 88 # cv2.line(img, (350, 100), (450, 400), (0, 255, 255)) 89 # cv2.line(img, (150, 250), (650, 250), (0, 255, 255)) 90 # cv2.line(img, (400, 75), (400, 425), (0, 255, 255)) 91 # cv2.line(img, (350, 300), (450, 200), (0, 255, 255)) 92 93 # 窗口裁剪直线 这里是显示裁剪之后的样子 94 CohenSutherland(0, 0, 260, 260) # 传递直线起点和终点坐标 95 CohenSutherland(400, 50, 200, 400) 96 CohenSutherland(350, 100, 450, 400) 97 CohenSutherland(150, 250, 650, 250) 98 CohenSutherland(400, 75, 400, 425) 99 CohenSutherland(350, 300, 450, 200) 100 # test() 101 102 # 窗口显示图形 103 cv2.imwrite('out1.jpg', img) # 生成一张图片 104 cv2.namedWindow('image', cv2.WINDOW_NORMAL) # 直接显示窗口 105 cv2.resizeWindow('image', 800, 500) # 定义frame的大小 106 cv2.imshow('image', img) # 显示图像 107 k = cv2.waitKey(0) # 等待键盘输入,为毫秒级 0表示一直等待 108 if k == 27: # 键盘上Esc键的键值 按下就会退出 设置好条件更加方便 109 cv2.destroyAllWindows() 110 111 112 # print('this message is from main function') 113 114 115 if __name__ == '__main__': 116 main() 117 # print('now __name__ is %s' % __name__) View Code

 

五.运行结果

裁剪前:

 

 

裁剪后:

 

 五.思考与收获

学会把思路理清后,自己能够写出基本框架的程序,一些不懂的知识就去及时百度,以后要系统学习python的库,感觉很好用,

在学习的过程中,也要加强做笔记的能力,多写博客吧。

 

 



【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3