рдкрд░реНрдпрд╛рд╡рд░рдг рдХреЗ рдирдХреНрд╢реЗ рдкрд░ рдкреНрд░рдХрд╛рд╢ рд╕реНрд░реЛрддреЛрдВ рдХреА рдорд╛рдиреНрдпрддрд╛

рдЫрд╡рд┐

рдпрд╣ рд▓реЗрдЦ рдкрд░реНрдпрд╛рд╡рд░рдг рдХреЗ рдорд╛рдирдЪрд┐рддреНрд░ (рдПрд▓рдбреАрдЖрд░ рдпрд╛ рдПрдЪрдбреАрдЖрд░) рдкрд░ рдПрдХ рдЕрдкреНрд░рддреНрдпрдХреНрд╖ рдкреНрд░рдХреНрд╖реЗрдкрдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреНрд░рдХрд╛рд╢ рд╕реНрд░реЛрддреЛрдВ рдХреЛ рдкрд╣рдЪрд╛рдирдиреЗ рдХреЗ рд▓рд┐рдП рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреЗ рдкрд╛рдпрдерди рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рдкреНрд░рд╕реНрддреБрдд рдХрд░рддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдорд╛рдореВрд▓реА рдмрджрд▓рд╛рд╡ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдЗрд╕реЗ рд╕рд░рд▓ рдкреГрд╖реНрдарднреВрдорд┐ рдЫрд╡рд┐рдпреЛрдВ рдпрд╛ рдХреНрдпреВрдмрд┐рдХ рдореИрдкреНрд╕ рдХреЗ рд╕рд╛рде рднреА рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреЗ рд╕рдВрднрд╛рд╡рд┐рдд рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдХреЗ рдЙрджрд╛рд╣рд░рдг: рдХрд┐рд░рдг рдЕрдиреБрд░реЗрдЦрдг рдХрд╛рд░реНрдпрдХреНрд░рдо рдЬрд┐рд╕рдореЗрдВ рдкреНрд░рд╛рдердорд┐рдХ рдкреНрд░рдХрд╛рд╢ рд╕реНрд░реЛрддреЛрдВ рдХреЛ рдкрд╣рдЪрд╛рдирдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ рддрд╛рдХрд┐ рдЙрдирд╕реЗ рдХрд┐рд░рдгреЗрдВ рдирд┐рдХрд▓ рд╕рдХреЗрдВ; rasterized рд░реЗрдВрдбрд░рд░реНрд╕ рдореЗрдВ, рдЗрд╕реЗ рдПрдХ рдкрд░реНрдпрд╛рд╡рд░рдг рдорд╛рдирдЪрд┐рддреНрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЫрд╛рдпрд╛ рдбрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ; рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рд╕реНрдкреЙрдЯрд▓рд╛рдЗрдЯ рдПрд▓рд┐рдорд┐рдиреЗрд╢рди рдХрд╛рд░реНрдпрдХреНрд░рдореЛрдВ рдореЗрдВ рднреА рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдПрдЖрд░ рдореЗрдВред

рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдореЗрдВ рдирд┐рдореНрди рдЪрд░рдг рд╣реЛрддреЗ рд╣реИрдВ:

  1. рдореВрд▓ рдЫрд╡рд┐ рдХреЗ рд╕рдВрдХрд▓реНрдк рдореЗрдВ рдХрдореА, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, 1024 рддрдХред
  2. рдЫрд╡рд┐ рдХреЛ рдЪрдордХ рдХреЗ рд▓рд┐рдП рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░реЗрдВ (luminance), рдпрджрд┐ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ, рдЫрд╡рд┐ рдзрдмреНрдмрд╛ рдХреЗ рд╕рд╛рдеред
  3. рдЕрд░реНрдз-рдореЛрдВрдЯреЗ рдХрд╛рд░реНрд▓реЛ рдкрджреНрдзрддрд┐ рдХрд╛ рдЕрдиреБрдкреНрд░рдпреЛрдЧред
  4. рдЧреЛрд▓рд╛рдХрд╛рд░ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рд╕реЗ рд╕рдорд╡рд░реНрддреА рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрдиред
  5. рдкрдбрд╝реЛрд╕реА рдХреА рдЪрдордХ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдЫрд╛рдирдиреЗ рдХреЗ рдирдореВрдиреЗред
  6. рдЙрдирдХреА рдЪрдордХ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдирдореВрдиреЛрдВ рдХреЛ рдХреНрд░рдордмрджреНрдз рдХрд░реЗрдВред
  7. рдпреВрдХреНрд▓рд┐рдбрд┐рдпрди рдореАрдЯреНрд░рд┐рдХ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдлрд╝рд┐рд▓реНрдЯрд░рд┐рдВрдЧ рдирдореВрдиреЗред
  8. рдмреНрд░реЗрд╕реЗрдирд╣реИрдо рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рдирдореВрдиреЗ рдЬреЛрдбрд╝рдирд╛ред
  9. рдЗрд╕рдХреА рдЪрдордХ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдкреНрд░рдХрд╛рд╢ рдХреНрд▓рд╕реНрдЯрд░ рдХреА рд╕реНрдерд┐рддрд┐ рдХреА рдЧрдгрдирд╛ред

рдЫрд╡рд┐рдпреЛрдВ рдХреЗ рд░рд┐рдЬрд╝реЙрд▓реНрдпреВрд╢рди рдХреЛ рдХрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрдИ рдПрд▓реНрдЧреЛрд░рд┐рджрдо рд╣реИрдВред рдмрд┐рд▓рд┐рдирд┐рдпрд░ рдлрд╝рд┐рд▓реНрдЯрд░рд┐рдВрдЧ рд╕рдмрд╕реЗ рддреЗрдЬрд╝ рдпрд╛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдореЗрдВ рдЖрд╕рд╛рди рд╣реИ, рдФрд░ рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдпрд╣ рдЬреНрдпрд╛рджрд╛рддрд░ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рд╕рдмрд╕реЗ рдЙрдкрдпреБрдХреНрдд рд╣реИред LDR рдФрд░ HDR рджреЛрдиреЛрдВ рдЫрд╡рд┐рдпреЛрдВ рдореЗрдВ рдЪрдордХ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдк рдорд╛рдирдХ рд╕реВрддреНрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

lum = img[:, :, 0] * 0.2126 + img[:, :, 1] * 0.7152 + img[:, :, 2] * 0.0722 

рдЗрд╕рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд, рдЖрдк рдмреНрд░рд╛рдЗрдЯ рдЗрдореЗрдЬ рдХреЗ рд▓рд┐рдП рдПрдХ рдорд╛рдореВрд▓реА рдмреНрд▓рд░ рд▓рдЧрд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, 1024 рдХреЗ рд░рд┐рдЬрд╝реЙрд▓реНрдпреВрд╢рди рд╡рд╛рд▓реА рдЗрдореЗрдЬ рдХреЗ рд▓рд┐рдП 1-2 рдкрд┐рдХреНрд╕рд▓, рд╕рднреА рд╣рд╛рдИ-рдлреНрд░реАрдХреНрд╡реЗрдВрд╕реА рдбрд┐рдЯреЗрд▓реНрд╕ (рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ, рд░рд┐рдЬрд╝реЙрд▓реНрдпреВрд╢рди рдореЗрдВ рдХрдореА рдХреЗ рдХрд╛рд░рдг) рдХреЛ рдЦрддреНрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдПред

рдЗрдХреНрд╡рд┐рдбрд┐рд╕реНрдЯреЗрдВрдЯ рдкреНрд░реЛрдЬреЗрдХреНрд╢рди


рдкрд░реНрдпрд╛рд╡рд░рдг рдХреЗ рдирдХреНрд╢реЛрдВ рдореЗрдВ рд╕рдмрд╕реЗ рдЖрдо рдкреНрд░рдХреНрд╖реЗрдкрдг рд╣реИ рд╕рдордХрд╛рд▓рд┐рдХ рдкреНрд░рдХреНрд╖реЗрдкрдг 3 ред рдореЗрд░рд╛ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдЕрдиреНрдп рдЕрдиреБрдорд╛рдиреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдкреИрдиреЛрд░рдорд┐рдХ рдФрд░ рдХреНрдпреВрдмрд┐рдХ рдореИрдкреНрд╕ рдХреЗ рд╕рд╛рде, рд╣рд╛рд▓рд╛рдВрдХрд┐, рд▓реЗрдЦ рдореЗрдВ рд╣рдо рдХреЗрд╡рд▓ рдПрдХ рд╕рдорд╛рди рд░реВрдк рд╕реЗ рдкреНрд░рд╛рдпреЛрдЬрд┐рдд рдкреНрд░рдХреНрд╖реЗрдкрдг рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВрдЧреЗред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ рдЖрдкрдХреЛ рдЫрд╡рд┐ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдХреЛ рд╕рд╛рдорд╛рдиреНрдп рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:

 pos[0] = x / width pos[1] = y / height 

рдлрд┐рд░ рд╣рдореЗрдВ рдЧреЛрд▓рд╛рдХрд╛рд░ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдФрд░ рдХрд╛рд░реНрдЯреЗрд╕рд┐рдпрди рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рд╕реЗ рдХрдиреНрд╡рд░реНрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЕрд░реНрдерд╛рддреНред ╧Ж рдФрд░ ╧Ж, рдЬрд╣рд╛рдВ ╬╕ = x * 2 and, рдФрд░ * = y * ╧Жред

 def sphereToEquirectangular(pos): invAngles = (0.1591, 0.3183) xy = (math.atan2(pos[1], pos[0]), math.asin(pos[2])) xy = (xy[0] * invAngles[0], xy[1] * invAngles[1]) return (xy[0] + 0.5, xy[1] + 0.5) def equirectangularToSphere(pos): angles = (1 / 0.1591, 1 / 0.3183) thetaPhi = (pos[0] - 0.5, pos[1] - 0.5) thetaPhi = (thetaPhi[0] * angles[0], thetaPhi[1] * angles[1]) length = math.cos(thetaPhi[1]) return (math.cos(thetaPhi[0]) * length, math.sin(thetaPhi[0]) * length, math.sin(thetaPhi[1])) 

рд╣реИрдорд░рд╕реНрд▓реА рд╕реИрдВрдкрд▓рд┐рдВрдЧ


рдЕрдЧрд▓рд╛ рдХрджрдо рдХреНрд╡рд╛рд╕реА-рдореЛрдВрдЯреЗ рдХрд╛рд░реНрд▓реЛ рдкрджреНрдзрддрд┐ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣реИрдорд░рд╕реНрд▓реЗ 2 рдирдореВрдирд╛:


рдЖрдк рдЕрдиреНрдп рдирдореВрдирд╛ рддрд░реАрдХреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреИрд╕реЗ рдХрд┐ рд╣реЛрд▓реНрдЯрди 4 , рд▓реЗрдХрд┐рди рд╣реИрдорд░реНрд╕рд▓реА рддреЗрдЬреА рд╕реЗ рд╣реИ рдФрд░ рдкреВрд░реЗ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рдирдореВрдиреЛрдВ рдХрд╛ рдЕрдЪреНрдЫрд╛ рд╡рд┐рддрд░рдг рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред рдпрджрд┐ рдкрд░реНрдпрд╛рд╡рд░рдг рдорд╛рдирдЪрд┐рддреНрд░ рдХреЗ рдмрдЬрд╛рдп рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдЫрд╡рд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рд╣реЛрд▓реНрдЯрди рд╡рд┐рдорд╛рди рдХреЗ рдирдореВрдиреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрдЪреНрдЫрд╛ рд╡рд┐рдХрд▓реНрдк рд╣реЛрдЧрд╛ред рд╣реИрдорд░рд╕реНрд▓реА рдирдореВрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрдирд┐рд╡рд╛рд░реНрдп рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╡реИрди рдбреЗрд░ рдХреЙрд░реНрдкреЗрдЯ рдХреА рдЬрдбрд╝реЛрдВ (рдкрдВрдХреНрддрд┐) рдХрд╛ рдЙрд▓рдЯрд╛ рд╣реИ, рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд▓рд┐рдП рд▓рд┐рдВрдХ 2 рджреЗрдЦреЗрдВред рдпрд╣рд╛рдБ рдЗрд╕рдХрд╛ рддреНрд╡рд░рд┐рдд рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИ:

 def vdcSequence(bits): bits = (bits << 16) | (bits >> 16) bits = ((bits & 0x55555555) << 1) | ((bits & 0xAAAAAAAA) >> 1) bits = ((bits & 0x33333333) << 2) | ((bits & 0xCCCCCCCC) >> 2) bits = ((bits & 0x0F0F0F0F) << 4) | ((bits & 0xF0F0F0F0) >> 4) bits = ((bits & 0x00FF00FF) << 8) | ((bits & 0xFF00FF00) >> 8) return float(bits) * 2.3283064365386963e-10 # / 0x100000000 def hammersleySequence(i, N): return (float(i) / float(N), vdcSequence(i)) 

рдлрд┐рд░ рд╣рдо рдЧреЛрд▓реЗ рдкрд░ рд╕рдорд╛рди рдЙрдкрд░рд┐рд╢рд╛рдпреА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ:

 def sphereSample(u, v): PI = 3.14159265358979 phi = v * 2.0 * PI cosTheta = 2.0 * u - 1.0 # map to -1,1 sinTheta = math.sqrt(1.0 - cosTheta * cosTheta); return (math.cos(phi) * sinTheta, math.sin(phi) * sinTheta, cosTheta) 

рд╣реИрдорд░рд╕реНрд▓реЗ рдХрд╛ рдирдореВрдирд╛ рд▓реЗрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдирдореВрдиреЗ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рдЬреЛ рдЫрд╡рд┐ рдХреЗ рд╕рдВрдХрд▓реНрдк рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдЧреЛрд▓рд╛рдХрд╛рд░ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рд╕реЗ рдХрд╛рд░реНрдЯреЗрд╢рд┐рдпрди рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рд╣реЛрддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ рд╕рдорддреБрд▓реНрдп рдХреЗ рд▓рд┐рдП:

  samplesMultiplier = 0.006 samples = int(samplesMultiplier * width * height) samplesList = [] # apply hammersley sampling for i in range(0, samples): xi = hammersleySequence(i, samples) xyz = sphereSample(xi[0], xi[1]) # to cartesian imagePos = sphereToEquirectangular(xyz) luminance = lum[imagePos[0] * width, imagePos[1] * height] 

рдпрд╣ рд╣рдореЗрдВ рдЙрди рдирдореВрдиреЛрдВ рдХрд╛ рдЕрдЪреНрдЫрд╛ рд╡рд┐рддрд░рдг рджреЗрдЧрд╛ рдЬреЛ рдкреНрд░рдХрд╛рд╢ рд╕реНрд░реЛрддреЛрдВ рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдХреЗ рд▓рд┐рдП рдЬрд╛рдВрдЪреЗ рдЬрд╛рдПрдВрдЧреЗ:


рдкреНрд░рдХрд╛рд╢ рд╕реНрд░реЛрддреЛрдВ рдХреЛ рдЫрд╛рдирдирд╛


рдлрд╝рд┐рд▓реНрдЯрд░рд┐рдВрдЧ рдХреЗ рдкрд╣рд▓реЗ рдкрд╛рд╕ рдореЗрдВ, рд╣рдо рд╕рднреА рдирдореВрдиреЛрдВ рдХреЛ рдЕрдирджреЗрдЦрд╛ рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ рдЪрдордХ рджрд╣рд▓реАрдЬ рд╕реЗ рдЕрдзрд┐рдХ рдирд╣реАрдВ рд╣реЛрддреЗ рд╣реИрдВ (рдПрдЪрдбреАрдЖрд░ рдХрд╛рд░реНрдб рдХреЗ рд▓рд┐рдП, рдпрд╣ рдЕрдзрд┐рдХ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ), рдФрд░ рдлрд┐рд░ рдЙрдирдХреА рдЪрдордХ рд╕реЗ рд╕рднреА рдирдореВрдиреЛрдВ рдХреЛ рдХреНрд░рдордмрджреНрдз рдХрд░реЗрдВ:

  localSize = int(float(12) * (width / 1024.0)) + 1 samplesList = [] # apply hammersley sampling for i in range(0, samples): xi = hammersleySequence(i, samples) xyz = sphereSample(xi[0], xi[1]) # to cartesian imagePos = sphereToEquirectangular(xyz) luminance = lum[imagePos [0] * width, imagePos [1] * height] sample = Sample(luminance, imagePos , xyz) luminanceThreshold = 0.8 #do a neighbour search for the maximum luminance nLum = computeNeighborLuminance(lum, width, height, sample.imagePos, localSize) if nLum > luminanceThreshold: samplesList.append(sample) samplesList = sorted(samplesList, key=lambda obj: obj.luminance, reverse=True) 

рдЕрдЧрд▓рд╛ рдкрд╛рд╕ рдпреВрдХреНрд▓рд┐рдбрд┐рдпрди рдореАрдЯреНрд░рд┐рдХ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдлрд╝рд┐рд▓реНрдЯрд░рд┐рдВрдЧ рдХрд░реЗрдЧрд╛ рдФрд░ рдкрд┐рдХреНрд╕реЗрд▓ рдХреЗ рдмреАрдЪ рдХреА рджрд╣рд▓реАрдЬ рджреВрд░реА (рдЫрд╡рд┐ рд░рд┐рдЬрд╝реЙрд▓реНрдпреВрд╢рди рдХреЗ рдЖрдзрд╛рд░ рдкрд░) - рдпрд╣ рдПрдХ рд╕реНрдерд╛рдирд┐рдХ рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛ рд╣реИ рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдЬрдЯрд┐рд▓рддрд╛ рдУ (рдПрди 2 ) рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:

  euclideanThreshold = int(float(euclideanThresholdPixel) * (width / 2048.0)) # filter based euclidian distance filteredCount = len(samplesList) localIndices = np.empty(filteredCount); localIndices.fill(-1) for i in range(0, filteredCount): cpos = samplesList[i].pos if localIndices[i] == -1: localIndices[i] = i for j in range(0, filteredCount): if i != j and localIndices[j] == -1 and distance2d(cpos, samplesList[j].pos) < euclideanThreshold: localIndices[j] = i 

рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рдирдореВрдиреЗ рдкреНрд░рдХрд╛рд╢ рд╕реНрд░реЛрддреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЛ рдХрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рд▓рдп рдЪрд░рдг рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЬрд╛рддреЗ рд╣реИрдВ:


рдкреНрд░рдХрд╛рд╢ рд╕реНрд░реЛрддреЛрдВ рдХрд╛ рд╡рд┐рд▓рдп


рдЕрдВрддрд┐рдо рдЪрд░рдг рдореЗрдВ, рдПрдХ рд╣реА рдкреНрд░рдХрд╛рд╢ рдХреНрд▓рд╕реНрдЯрд░ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдирдореВрдиреЛрдВ рдХрд╛ рд╡рд┐рд▓рдп рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдмреНрд░реЗрд╕реЗрдирд╣реИрдо рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЙрдЪреНрдЪрддрдо рдЪрдордХ рдХреЗ рд╕рд╛рде рдирдореВрдиреЛрдВ рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдСрд░реНрдбрд░ рдХрд┐рдП рдЧрдП рд╣реИрдВред рдЬрдм рд╣рдореЗрдВ рдПрдХ рдкреНрд░рдХрд╛рд╢ рд╕реНрд░реЛрдд рдорд┐рд▓рддрд╛ рд╣реИ рдЬреЛ рдмреНрд░реЗрд╕реЗрдирд╣реИрдо рдкрд░реАрдХреНрд╖рдг рдХреЛ рд╕рдВрддреБрд╖реНрдЯ рдХрд░рддрд╛ рд╣реИ, рддреЛ рд╣рдо рдЗрд╕рдХреА рд╕реНрдерд┐рддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рд░рди рдХреЗ рд╡рдЬрди рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╕реНрд░реЛрдд рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░рддреЗ рд╣реИрдВ:

  # apply bresenham check and compute position of the light clusters lights = [] finalIndices = np.empty(filteredCount); finalIndices.fill(-1) for i in localIndices: sample = samplesList[i] startPos = sample.pos if finalIndices[i] == -1: finalIndices[i] = i light = Light() light.originalPos = np.array(sample.pos) # position of the local maxima light.worldPos = np.array(sample.worldPos) light.pos = np.array(sample.pos) light.luminance = sample.luminance for j in localIndices: if i != j and finalIndices[j] == -1: endPos = samplesList[j].pos if bresenhamCheck(lum, width, height, startPos[0], startPos[1], endPos[0], endPos[1]): finalIndices[j] = i # compute final position of the light source sampleWeight = samplesList[j].luminance / sample.luminance light.pos = light.pos + np.array(endPos) * sampleWeight light.pos = light.pos / (1.0 + sampleWeight) imagePos = light.pos * np.array([1.0 / width, 1.0 / height) light.worldPos = equirectangularToSphere(imagePos) lights.append(light) 

рдмреНрд░реЗрд╕реЗрдирд╣реИрдо рдлрд╝рдВрдХреНрд╢рди рдПрдХ рдирд┐рд░рдВрддрд░ рд░реЗрдЦрд╛ рдХреА рдЬрд╛рдВрдЪ рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рд╕рдорд╛рди рдЪрдордХ рд╣реЛрддреА рд╣реИред рдпрджрд┐ рд╡рд░реНрддрдорд╛рди рдкрд┐рдХреНрд╕реЗрд▓ рдореЗрдВ рдбреЗрд▓реНрдЯрд╛ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд╕реАрдорд╛ рд╕реЗ рдЕрдзрд┐рдХ рд╣реИ, рддреЛ рдЬрд╛рдБрдЪ рд╡рд┐рдлрд▓ рд╣реЛ рдЬрд╛рддреА рд╣реИ:

 def bresenhamCheck(lum, imageSize, x0, y0, x1, y1): dX = int(x1 - x0) stepX = int((dX > 0) - (dX < 0)) dX = abs(dX) << 1 dY = int(y1 - y0) stepY = int((dY > 0) - (dY < 0)) dY = abs(dY) << 1 luminanceThreshold = 0.15 prevLum = lum[x0][y0] sumLum = 0.0 c = 0 if (dX >= dY): # delta may go below zero delta = int (dY - (dX >> 1)) while (x0 != x1): # reduce delta, while taking into account the corner case of delta == 0 if ((delta > 0) or (delta == 0 and (stepX > 0))): delta -= dX y0 += stepY delta += dY x0 += stepX sumLum = sumLum + min(lum[x0][y0], 1.25) c = c + 1 if(abs(sumLum / c - prevLum) > luminanceThreshold and (sumLum / c) < 1.0): return 0 else: # delta may go below zero delta = int(dX - (dY >> 1)) while (y0 != y1): # reduce delta, while taking into account the corner case of delta == 0 if ((delta > 0) or (delta == 0 and (stepY > 0))): delta -= dY x0 += stepX delta += dX y0 += stepY sumLum = sumLum + min(lum[x0][y0], 1.25) c = c + 1 if(abs(sumLum / c - prevLum) > luminanceThreshold and (sumLum / c) < 1.0): return 0 return 1 

рдпрд╣ рдзреНрдпрд╛рди рджрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐, рдпрджрд┐ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ, рддреЛ рдмреНрд░реЗрд╕реЗрдирд╣реИрдо рдкрд░реАрдХреНрд╖рдг рдореЗрдВ рд╕реБрдзрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬрд┐рд╕рд╕реЗ рдирдореВрдиреЛрдВ рдХрд╛ рдмреЗрд╣рддрд░ рд╡рд┐рд▓рдп рд╣реЛ рдЬрд╛рдПрдЧрд╛, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрд╣ рдЫрд╡рд┐ рдХреЗ рдХрд┐рдирд╛рд░реЛрдВ рдкрд░ рд╕реНрдерд┐рдд рдкреНрд░рдХрд╛рд╢ рд╕реНрд░реЛрддреЛрдВ рдХреЗ рдХреНрд╖реИрддрд┐рдЬ рд╣рд╕реНрддрд╛рдВрддрд░рдг рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдЖрд╕рд╛рдиреА рд╕реЗ рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рддрд╛рдХрд┐ рдпрд╣ рдкреНрд░рдХрд╛рд╢ рд╕реНрд░реЛрддреЛрдВ рдХреЗ рдХреНрд╖реЗрддреНрд░ рдХрд╛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛ рд╕рдХреЗред рдПрдХ рдФрд░ рд╕реБрдзрд╛рд░: рдЖрдк рдПрдХ рджреВрд░реА рд╕реАрдорд╛ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ рддрд╛рдХрд┐ рдЖрдк рдЙрди рдирдореВрдиреЛрдВ рдХреЛ рд╕рдВрдпреЛрдЬрд┐рдд рди рдХрд░реЗрдВ рдЬреЛ рдмрд╣реБрдд рджреВрд░ рд╣реИрдВред рдЕрдВрддрд┐рдо рдкрд░рд┐рдгрд╛рдо:


рдмреНрд▓реВ рдкреНрд░рдХрд╛рд╢ рд╕рдореВрд╣реЛрдВ рдХреЗ рд╕реНрдерд╛рдиреАрдп рдореИрдХреНрд╕рд┐рдорд╛ рдХреЛ рджрд░реНрд╢рд╛рддрд╛ рд╣реИ, рдиреАрд▓реЗ рдкреНрд░рдХрд╛рд╢ рд╕реНрд░реЛрддреЛрдВ рдХреА рдЕрдВрддрд┐рдо рд╕реНрдерд┐рддрд┐ рдХреЛ рджрд░реНрд╢рд╛рддрд╛ рд╣реИ, рдФрд░ рд▓рд╛рд▓ рд░рдВрдЧ рдЙрди рдирдореВрдиреЛрдВ рдХреЛ рджрд░реНрд╢рд╛рддрд╛ рд╣реИ рдЬреЛ рдПрдХ рд╣реА рдкреНрд░рдХрд╛рд╢ рдХреНрд▓рд╕реНрдЯрд░ рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рд╣реИрдВ рдФрд░ рд▓рд╛рдЗрдиреЛрдВ рджреНрд╡рд╛рд░рд╛ рдЬреБрдбрд╝реЗ рд╣реБрдП рд╣реИрдВред

рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЗ рдЕрдиреНрдп рдЙрджрд╛рд╣рд░рдг:




  1. Maciej Laskowski рджреНрд╡рд╛рд░рд╛ рдбрд┐рдЬрд┐рдЯрд▓ рддрд╕реНрд╡реАрд░реЛрдВ рдореЗрдВ рдкреНрд░рдХрд╛рд╢ рд╕реНрд░реЛрддреЛрдВ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдирд╛
  2. рд╣реИрдорд░рд╕реНрд▓реЗ рдкреЙрдЗрдВрдЯреНрд╕ рдСрдирд░ рдж рд╣реЛрд▓реНрдорд░ рджреНрд╡рд╛рд░рд╛ рд╣реЛрд▓реНрдЧрд░ рдбреИрдорд░реНрдЯреНрдЬрд╝
  3. рдкреЙрд▓ рд░реАрдб рджреНрд╡рд╛рд░рд╛ рд╕рдорд╛рди рдЕрдкреНрд░рддреНрдпрдХреНрд╖ рдкреНрд░рдХреНрд╖реЗрдкрдг
  4. Tien-Tsin рд╡реЛрдВрдЧ рджреНрд╡рд╛рд░рд╛ рд╣реИрдорд░реНрд╕рд▓реА рдФрд░ рд╣реИрд▓реНрдЯрди рдЕрдВрдХ рдХреЗ рд╕рд╛рде рдирдореВрдирд╛рдХрд░рдг

Source: https://habr.com/ru/post/hi458598/


All Articles