plot line with angle 60 degree

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

how to plot line with angle 60 degree

问题

以下是翻译好的部分,不包括代码部分:

"我有一些RGB颜色数据,我想要将其绘制到2D的CIEab颜色通道中,使用a和b的数据。然后,我需要用一个60度的线将我的数据分开。

我已经使用以下代码绘制了a和b:

图像_RGB = np.uint8([[[236,195,187],[224,175,167] ,[211,160,147] ,[199,141,130] ,[182,126,113] ,[164,106,95] ,[144, 92, 79] ,[122, 74, 67] ,[101, 61, 53] ,[78, 47, 44]],
...
lab_image = toLAB(image_RGB)

我得到的结果如下图所示:
plot line with angle 60 degree

但我不知道如何制作60度的线?

我想要的结果如下图所示。有一条绿色的线,倾斜60度。我想要制作类似于那样的线。"
plot line with angle 60 degree
图片来源:https://www.researchgate.net/publication/325286809_Brief_overview_of_PANTONE_SkinTone_Guide_chart_in_CIELab_color

英文:

i have some data of colors in RGB, i want to plot it to CIEab color channel in 2d which is use the data of a & b. then i need to separate my data with a line which is 60 degree

i have done plot a&b with this code below :

import cv2
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

image_RGB = np.uint8([[[236,195,187],[224,175,167]  ,[211,160,147]  ,[199,141,130]  ,[182,126,113]  ,[164,106,95]   ,[144, 92, 79]  ,[122, 74, 67]  ,[101, 61, 53]  ,[78, 47, 44]],
                    [[234, 196, 186],[222, 178, 161],[209, 162, 146],[193, 143, 123],[178, 128, 105],[161, 110, 93] ,[142, 93, 77]  ,[121, 77, 61]  ,[99, 63, 49]   ,[77, 49, 39]],
                    [[232, 198, 179],[220, 179, 160],[206, 163, 139],[191, 145, 121],[176, 129, 103],[157, 111, 87] ,[139, 96, 71]  ,[117, 80, 58]  ,[97, 64, 45]   ,[77, 49, 37]],
                    [[229, 200, 177],[218, 182, 155],[204, 163, 136],[188, 147, 119],[170, 129, 99] ,[154, 113, 85] ,[134, 95, 66]  ,[117, 81, 55]  ,[93, 65, 43]   ,[73, 52, 35]],
                    [[225, 199, 176],[213, 182, 152],[200, 165, 133],[185, 149, 117],[167, 131, 99] ,[149, 114, 82] ,[131, 98, 65]  ,[112, 81, 52]  ,[92, 66, 41]   ,[71, 52, 37]],
                    [[224,201,176]  ,[210,184,151]  ,[196,166,130]  ,[181,152,112]  ,[166,132,94]   ,[146,117,77]   ,[126, 100, 63] ,[109, 85, 50]  ,[89, 68, 41]   ,[70, 53, 37]],
                    [[163,107,72]   ,[0,0,0]  ,[255,255,255]  ,[255,255,255]  ,[255,255,255]  ,[255,255,255]  ,[255,255,255]  ,[255,255,255]  ,[255,255,255]  ,[255,255,255]]
                    ])

def toLAB(image, input_type = 'RGB'):
    conversion = cv2.COLOR_BGR2Lab if input_type == 'BGR' else cv2.COLOR_RGB2Lab
    image_LAB = cv2.cvtColor(image, conversion)
    print("LAB : ", image_LAB)

    y,x,z = image_LAB.shape
    LAB_flat = np.reshape(image_LAB, [y*x,z])
    print("LAB FLAT : ", LAB_flat)

    colors = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) if input_type == 'BGR' else image
    colors = np.uint8([[[255,0,0],  [255,0,0],  [255,0,0],  [255,0,0],  [255,0,0],  [255,0,0],  [255,0,0],  [255,0,0],  [255,0,0],  [255,0,0]],
                       [[255,0,0],  [255,0,0],  [255,0,0],  [255,0,0],  [255,0,0],  [255,0,0],  [255,0,0],  [255,0,0],  [255,0,0],  [255,0,0]],
                       [[0,255,0],  [0,255,0],  [0,255,0],  [0,255,0],  [0,255,0],  [0,255,0],  [0,255,0],  [0,255,0],  [0,255,0],  [0,255,0]],
                       [[0,255,0],  [0,255,0],  [0,255,0],  [0,255,0],  [0,255,0],  [0,255,0],  [0,255,0],  [0,255,0],  [0,255,0],  [0,255,0]],
                       [[255,255,0],[255,255,0],[255,255,0],[255,255,0],[255,255,0],[255,255,0],[255,255,0],[255,255,0],[255,255,0],[255,255,0]],
                       [[255,255,0],[255,255,0],[255,255,0],[255,255,0],[255,255,0],[255,255,0],[255,255,0],[255,255,0],[255,255,0],[255,255,0]],
                       [[0,0,255],  [0,0,0],    [0,0,0],    [0,0,0],    [0,0,0],    [0,0,0],    [0,0,0],    [0,0,0],    [0,0,0],    [0,0,0]]
                       ])
    print("colors : ", colors)
    colors = np.reshape(colors, [y*x,z])/255.

    fig = plt.figure()
    ax = fig.add_subplot(111, projection='rectilinear')
    ax.scatter(x=LAB_flat[:,2], y=LAB_flat[:,1], s=10,  c=colors, lw=0)
    ax.set_xlabel('A')
    ax.set_ylabel('B')
    # ax = fig.add_subplot(111, projection='3d')
    # ax.scatter(xs=LAB_flat[:,2], ys=LAB_flat[:,1], zs=LAB_flat[:,0], s=10,  c=colors, lw=0)
    # ax.set_xlabel('A')
    # ax.set_ylabel('B')
    # ax.set_zlabel('L')

    print(colors)
    plt.show()

    return image_LAB 

lab_image = toLAB(image_RGB)

the result what i get is like this
plot line with angle 60 degree

but i don't know how to make line of 60 degree?

the result i want is like the image below. there is a green line with 60 degrees slope. i want to make the line like that
plot line with angle 60 degree
image from : https://www.researchgate.net/publication/325286809_Brief_overview_of_PANTONE_SkinTone_Guide_chart_in_CIELab_color

答案1

得分: 1

x = [1,2,3,4,5]
y = [1,2,3,4,5]

plt.scatter(x, y)

# 蓝色虚线,起点(1,1),终点(5,4)
plt.plot((1,5), (1,4), '--')

# 橙色实线,起点(1,1),终点(5,6)
plt.plot((1,5), (1,6), '-')

plt.plot((x1, x2), (y1, y2), '-')  # 使用三角函数来找 x1、x2、y1、y2

或者使用

# 在这种情况下,斜率 = √3 或 1.732
斜率 = (y2 - y1) / (x2 - x1)
plt.axline((0, 0), slope=斜率)

# 在这行代码后添加你的代码
...
code before
...

ax.scatter(x=LAB_flat[:,2], y=LAB_flat[:,1], s=10, c=colors, lw=0)
ax.axline((0, 0), slope=1.732)
ax.set_xlabel('A')

...
code after
...

[slope equation](https://www.cuemath.com/slope-formula)

如果你已经有 x1, y1 和 x2, y2请使用 (y2 - y1) / (x2 - x1)
如果你得到角度 theta请使用 tan(theta)不要忘记将度数转换为弧度),或者使用 Google 查找 [tan 60 度](https://www.google.com/search?q=tan+60+degrees&sxsrf=APwXEdf5hDmV4m6jhIag5GpVRY33habmtg%3A1680593008241&ei=cNArZIOJDtKOseMP2dGtkAo&oq=tan+60&gs_lcp=Cgxnd3Mtd2l6LXNlcnAQAxgAMgcIIxCwAxAnMgoIABBHENYEELADMgoIABBHENYEELADMgoIABBHENYEELADMgoIABBHENYEELADMgoIABBHENYEELADMgoIABBHENYEELADMgoIABBHENYEELADMgoIABBHENYEELADMgoIABBHENYEELADMgoIABCKBRCwAxBDSgQIQRgAUABYAGCCCmgBcAF4AIABAIgBAJIBAJgBAMgBCsABAQ&sclient=gws-wiz-serp)

[参考 `pyplot.axline`](https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.axline.html)

可能重复的问题: https://stackoverflow.com/questions/7941226/how-to-add-line-based-on-slope-and-intercept-in-matplotlib
英文:
x = [1,2,3,4,5]
y = [1,2,3,4,5]

plt.scatter(x,y)

# blue line start at 1,1 end 5,4
plt.plot((1,5), (1,4), '--')

# orange line start at 1,1 end 5,6 
plt.plot((1,5), (1,6), '-') 

plot line with angle 60 degree

plt.plot((x1,x2), (y1,y2), '-')

and use some trigonometry to find x1 x2 and y1 y2

or use

# in this case slope = √3 or 1.732
slope = y2-y1 / x2-x1
plt.axline((0, 0), slope=slope)

you can add my code after this line

...
code before
...
ax.scatter(x=LAB_flat[:,2], y=LAB_flat[:,1], s=10,  c=colors, lw=0)
ax.axline((0, 0), slope=1.732)
ax.set_xlabel('A')
...
code after 
...

slope equation

if you got x1,y1 and x2,y2, use y2-y1 / x2-x1
if you get theta, use tan theta (don't forget to convert degree to radian) or use google to find tan 60 degree

Reference for pyplot.axline

Possibly duplicate of: https://stackoverflow.com/questions/7941226/how-to-add-line-based-on-slope-and-intercept-in-matplotlib

答案2

得分: 1

这段代码绘制了两条线:

  1. 一条60度线(绿色),用于分离数据以最小化错误分类。在这种情况下,有一个红点被错误分类。

  2. 一条最佳角度线(品红色),完美地分离数据,没有任何错误分类。请注意:尽管该线似乎穿过一个黄点和一个红点,但实际上它只在黄点上方和红点下方经过。找到的最佳角度是52.12度。

此代码还包括一些关于LAB颜色空间的转换和图形绘制的功能。

在代码的最后,lab_image 变量包含了通过 toLAB 函数转换的 LAB 颜色空间图像。

英文:

This code plots two lines:

  1. a 60-degree line (green color) that separates data with minimal misclassification. In this case, one red point is misclassified.

  2. a best-angle-line (magenta color) that separates data perfectly without any misclassification. Note: Even though the line may seem passing through one yellow point and one red point, actually it is passing just above the yellow point and just below the red point. Maximum best angle is found to be 52.12 degrees.

image_RGB = np.uint8([[[236,195,187],[224,175,167]  ,[211,160,147]  ,[199,141,130]  ,[182,126,113]  ,[164,106,95]   ,[144, 92, 79]  ,[122, 74, 67]  ,[101, 61, 53]  ,[78, 47, 44]],
                    [[234, 196, 186],[222, 178, 161],[209, 162, 146],[193, 143, 123],[178, 128, 105],[161, 110, 93] ,[142, 93, 77]  ,[121, 77, 61]  ,[99, 63, 49]   ,[77, 49, 39]],
                    [[232, 198, 179],[220, 179, 160],[206, 163, 139],[191, 145, 121],[176, 129, 103],[157, 111, 87] ,[139, 96, 71]  ,[117, 80, 58]  ,[97, 64, 45]   ,[77, 49, 37]],
                    [[229, 200, 177],[218, 182, 155],[204, 163, 136],[188, 147, 119],[170, 129, 99] ,[154, 113, 85] ,[134, 95, 66]  ,[117, 81, 55]  ,[93, 65, 43]   ,[73, 52, 35]],
                    [[225, 199, 176],[213, 182, 152],[200, 165, 133],[185, 149, 117],[167, 131, 99] ,[149, 114, 82] ,[131, 98, 65]  ,[112, 81, 52]  ,[92, 66, 41]   ,[71, 52, 37]],
                    [[224,201,176]  ,[210,184,151]  ,[196,166,130]  ,[181,152,112]  ,[166,132,94]   ,[146,117,77]   ,[126, 100, 63] ,[109, 85, 50]  ,[89, 68, 41]   ,[70, 53, 37]],
                    [[163,107,72]   ,[0,0,0]  ,[255,255,255]  ,[255,255,255]  ,[255,255,255]  ,[255,255,255]  ,[255,255,255]  ,[255,255,255]  ,[255,255,255]  ,[255,255,255]]
                    ])

def toLAB(image, input_type = 'RGB'):
    conversion = cv2.COLOR_BGR2Lab if input_type == 'BGR' else cv2.COLOR_RGB2Lab
    image_LAB = cv2.cvtColor(image, conversion)
    #print("LAB : ", image_LAB)

    y,x,z = image_LAB.shape
    LAB_flat = np.reshape(image_LAB, [y*x,z])
#     print("LAB FLAT : ", LAB_flat)

    colors = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) if input_type == 'BGR' else image
    colors = np.uint8([[[255,0,0],  [255,0,0],  [255,0,0],  [255,0,0],  [255,0,0],  [255,0,0],  [255,0,0],  [255,0,0],  [255,0,0],  [255,0,0]],
                       [[255,0,0],  [255,0,0],  [255,0,0],  [255,0,0],  [255,0,0],  [255,0,0],  [255,0,0],  [255,0,0],  [255,0,0],  [255,0,0]],
                       [[0,255,0],  [0,255,0],  [0,255,0],  [0,255,0],  [0,255,0],  [0,255,0],  [0,255,0],  [0,255,0],  [0,255,0],  [0,255,0]],
                       [[0,255,0],  [0,255,0],  [0,255,0],  [0,255,0],  [0,255,0],  [0,255,0],  [0,255,0],  [0,255,0],  [0,255,0],  [0,255,0]],
                       [[255,255,0],[255,255,0],[255,255,0],[255,255,0],[255,255,0],[255,255,0],[255,255,0],[255,255,0],[255,255,0],[255,255,0]],
                       [[255,255,0],[255,255,0],[255,255,0],[255,255,0],[255,255,0],[255,255,0],[255,255,0],[255,255,0],[255,255,0],[255,255,0]],
                       [[0,0,255],  [0,0,0],    [0,0,0],    [0,0,0],    [0,0,0],    [0,0,0],    [0,0,0],    [0,0,0],    [0,0,0],    [0,0,0]]
                       ])
    
    
    colors = np.reshape(colors, [y*x,z])/255.
    
    # get indices of red and yellow colors
    red_index = np.all(colors==[1.,0.,0.],axis=1)
    yellow_index = np.all(colors==[1.,1.,0.],axis=1)
    
    # slice interesting data points, red and yellow
    LAB_red = LAB_flat[red_index]
    LAB_yellow = LAB_flat[yellow_index]
    
    fig = plt.figure(figsize=(10,8))
    ax = fig.add_subplot(111, projection='rectilinear')
    # plot red points
    ax.scatter(x=LAB_red[:,2], y=LAB_red[:,1], s=10,  c='red', lw=0)
    # plot yellow points
    ax.scatter(x=LAB_yellow[:,2], y=LAB_yellow[:,1], s=10,  c='yellow', lw=0)
    
    # a formula to get y2 given other params
    def get_y(X1,X2,Y1,angle):
        return Y1 + (X2-X1) * np.tan(np.radians(angle))
    
    # (141,135) is one the extreme yellow points that stays close to separator line
    # (141,135) is obtained from LAB_flat data corresponding to yellow color
    # use that as hinge point (x_ref,y_ref) to change angle
    # x0 = 100 is randomly selected for plotting purpose and y0 will be calculated for given angle
    # x2 = 200 is randomly selected for plotting purpose and y2 will be calculated for given angle
    # epsilon, a small value, to keep the line just above the reference yellow hinge point
    
    epsilon = 1e-4
    x_ref = 141.
    y_ref = 135.+ epsilon
    
    x0 = 100.
    x2 = 200.
    
    y0 = get_y(x_ref,x0,y_ref,60)
    y2 = get_y(x_ref,x2,y_ref,60)
    
    # plot the 60-degree green line
    plt.plot((x0,x2),(y0,y2),c='g',label='60-degree-line')
    
    # find the best separating angle 
    LAB_red_X = LAB_red[:,2]
    LAB_red_Y = LAB_red[:,1]
    
    # reduce angle value starting fron 60
    for new_angle in np.arange(60.,40.,-0.01):
        
        # get Y values for all red X values for given angle
        y_pred = get_y(x_ref, LAB_red_X, y_ref, new_angle)
        
        # all actual red points should fall above the line
        if (LAB_red_Y > y_pred).all():
            # we found the best angle
            print(new_angle)
            # stop iteration
            break
    
    # plot a line with the best separating angle
    y0 = get_y(x_ref,x0,y_ref,new_angle)
    y2 = get_y(x_ref,x2,y_ref,new_angle)
    
    # plot the best-degree line (magenta color)
    plt.plot((x0,x2),(y0,y2),'--',c='magenta',label=f'{new_angle:0.2f}-degree-line')
    
    # show image to the interesting region only
    plt.xlim([125,160])
    plt.ylim([125,160])
    
    ax.set_xlabel('A')
    ax.set_ylabel('B')
    plt.legend()
    plt.show()

    return image_LAB 

lab_image = toLAB(image_RGB)

huangapple
  • 本文由 发表于 2023年4月4日 13:58:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/75925933.html
匿名

发表评论

匿名网友

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

确定