Как правильно подогнать данные к эллипсу с помощью python (odr) - PullRequest
0 голосов
/ 13 октября 2019

У меня есть x и y координаты части эллипса, извлеченной из изображения, поэтому естественно, что в нем будет небольшой шум.

the ellipse that is gonna be processed

тогдая хочу подогнать эллипс под общее уравнение его: Ax^2+Bxy+Cy^2+Dx+Ey+F=0, поэтому я использовал библиотеку odr в scipy:

from scipy import odr

def conic(beta, x): #conic equation of ellipse
    return beta[0]*(x[0])**2 + beta[1]*(x[1]*x[0])+beta[2]*(x[1])**2+beta[3]*x[0]+beta[4]*x[1]+beta[5]
x=[229, 228, 229, 230, 230, 227, 228, 231, 231, 226, 227, 232, 225, 226, 232, 233, 224, 225, 233, 234, 223, 224, 234, 235, 222, 223, 235, 236, 221, 222, 236, 220, 221, 236, 237, 219, 220, 237, 238, 218, 219, 238, 239, 217, 218, 239, 216, 217, 239, 240, 215, 216, 240, 241, 214, 215, 241, 213, 214, 241, 242, 212, 213, 242, 243, 211, 212, 243, 244, 210, 211, 244, 209, 210, 244, 245, 208, 209, 245, 246, 207, 208, 246, 206, 207, 247, 205, 206, 247, 204, 248, 203, 203, 248, 202, 202, 249, 201, 201, 249, 200, 200, 202, 250, 199, 250, 251, 198, 198, 251, 252, 197, 197, 252, 196, 253, 195, 253, 254, 194, 194, 254, 255, 193, 193, 254, 192, 192, 255, 191, 191, 255, 190, 255, 256, 189, 189, 256, 188, 257, 187, 257, 186, 186, 258, 185, 185, 258, 184, 259, 183, 259, 182, 260, 181, 181, 260, 180, 261, 179, 179, 261, 178, 178, 261, 262, 177, 177, 262, 176, 263, 175, 263, 174, 264, 173, 264, 172, 264, 171, 264, 265, 170, 170, 265, 169, 169, 266, 168, 168, 266, 167, 266, 166, 266, 165, 267, 164, 267, 163, 267, 162, 162, 268, 161, 268, 160, 268, 159, 269, 158, 158, 269, 157, 269, 156, 269, 155, 269, 154, 270, 153, 270, 152, 270, 151, 270, 150, 150, 271, 149, 271, 148, 271, 147, 147, 271, 146, 271, 145, 272, 144, 272, 143, 272, 142, 272, 141, 272, 140, 272, 139, 272, 138, 272, 137, 272, 136, 273, 135, 272, 134, 272, 133, 272, 132, 273, 131, 273, 130, 273, 129, 273, 128, 273, 127, 273, 126, 273, 125, 273, 124, 273, 123, 272, 122, 272, 121, 272, 120, 272, 119, 272, 118, 272, 117, 272, 116, 272, 115, 272, 114, 272, 113, 272, 112, 272, 111, 271, 110, 271, 109, 271, 108, 270, 107, 270, 106, 270, 105, 270, 104, 269, 103, 269, 102, 269, 101, 268, 100, 267, 268, 99, 99, 267, 98, 98, 266, 97, 97, 266, 96, 96, 265, 95, 95, 265, 94, 94, 264, 93, 93, 92, 92, 91, 90, 89, 89]
y=[249, 250, 250, 248, 249, 251, 251, 247, 248, 252, 252, 246, 253, 253, 245, 245, 254, 254, 244, 244, 255, 255, 243, 243, 256, 256, 242, 242, 257, 257, 241, 258, 258, 240, 240, 259, 259, 239, 239, 260, 260, 238, 238, 261, 261, 237, 262, 262, 236, 236, 263, 263, 235, 235, 264, 264, 234, 265, 265, 233, 233, 266, 266, 232, 232, 267, 267, 231, 231, 268, 268, 230, 269, 269, 229, 229, 270, 270, 228, 228, 271, 271, 227, 272, 272, 226, 273, 273, 225, 274, 224, 274, 275, 223, 275, 276, 222, 276, 277, 221, 277, 278, 278, 220, 278, 219, 219, 278, 279, 218, 218, 279, 280, 217, 280, 216, 280, 215, 215, 280, 281, 214, 216, 281, 282, 213, 282, 283, 212, 283, 284, 211, 284, 210, 210, 284, 285, 209, 285, 208, 286, 207, 286, 287, 206, 287, 288, 205, 288, 204, 288, 203, 289, 202, 289, 290, 201, 290, 200, 290, 291, 199, 291, 292, 198, 198, 292, 293, 197, 293, 196, 294, 195, 294, 194, 294, 193, 294, 192, 294, 191, 191, 294, 295, 190, 295, 296, 189, 296, 297, 188, 297, 187, 298, 186, 298, 185, 298, 184, 298, 183, 298, 299, 182, 299, 181, 300, 180, 300, 179, 300, 301, 178, 301, 177, 302, 176, 302, 175, 302, 174, 301, 173, 301, 172, 302, 171, 302, 303, 170, 303, 169, 304, 168, 304, 305, 167, 305, 166, 305, 165, 305, 164, 305, 163, 305, 162, 305, 161, 305, 160, 305, 159, 305, 158, 305, 157, 305, 156, 305, 155, 305, 154, 305, 153, 305, 152, 305, 151, 305, 150, 305, 149, 305, 148, 305, 147, 306, 146, 306, 145, 306, 144, 306, 143, 306, 142, 306, 141, 306, 140, 306, 139, 306, 138, 306, 137, 305, 136, 305, 135, 305, 134, 305, 133, 306, 132, 306, 131, 305, 130, 305, 129, 304, 128, 304, 127, 303, 126, 303, 125, 302, 124, 302, 123, 302, 122, 302, 121, 301, 120, 120, 300, 301, 119, 299, 300, 118, 298, 299, 117, 297, 298, 116, 296, 297, 115, 295, 296, 114, 294, 295, 293, 294, 293, 292, 291, 292]
beta0 = [ 200, 200, 200,200,200,200] #initial values of coefficients foundout that changing initial values doesnt affect the results very much
lsc_data  = odr.Data([x, y],y=1)
lsc_model = odr.Model(cononic, implicit=True)
lsc_odr   = odr.ODR(lsc_data, lsc_model, beta0)
lsc_out   = lsc_odr.run()
[A,B,C,D,E,F]=(lsc_out.beta/min(lsc_out.beta))*1000 #final coefficient the 1000 multiply is because the
                                                    #results are small so it makes them bigger

он выполняет свою работу и соответствует уравнению, а иногда и корректно, но проблемав том, что в большинстве случаев он либо не является эллипсом (его гиперболой), либо не является правильным эллипсом, либо иногда вырожденным, так что есть ли способ приспособить эти данные к эллипсу с условиями, основанными на B^2-4AC<0 и C*delta<0на это:

general ellipse from wikipedia

...