সিভি 2 এর সময় পাইথনের ফলাফল পরিবর্তন হয় od রডরিগস গণনা


19

আমি যদি চালাতে পারি:

import numpy as np
import cv2

def changes():
    rmat=np.eye(4)
    tvec=np.zeros(3)
    (rvec, jacobian)=cv2.Rodrigues(rmat)
    print rvec

for i in range(2):
    changes()

আমি পাই:

[[6.92798859e-310]
 [2.19380404e-316]
 [1.58101007e-322]]
[[0.]
 [0.]
 [0.]]

সুতরাং changes()পরিবর্তন থেকে ফলাফল ।

আমি বুঝতে পারি না এটি কেন এবং tvec=np.zeros(3)লাইনটি মন্তব্য করা হলে এটি পরিবর্তন করা বন্ধ করে দেয়, তা আমাকে অনুভব করে যে এটি সিস্টেমে একটি বাগ।


"ই -310" ভাসমান সংখ্যা 0 এর খুব কাছাকাছি রয়েছে বলে মনে হচ্ছে পাইথন ভাসমান সংখ্যার উপস্থাপনা সহ সাধারণ ইস্যুটির মতো, যা মেমোরির প্রতিটি বরাদ্দের ক্ষেত্রে পৃথক হতে পারে।
আরিরেজ

এটি মারাত্মক অদ্ভুত ... আমার কাছেও এটি একটি বাগের মতো দেখাচ্ছে।
জুলিয়ান

1
আইএমওর প্রধান বিষয় হ'ল টিভেককে অ্যারে হিসাবে সংজ্ঞায়িত করা (তবে কোনও ইনট বা স্ট্রিং হিসাবে নয়) এর একটি প্রভাব রয়েছে ... এবং একবার আপনি এটি সম্পন্ন করার পরে, আর পিছনে ফিরে যাবেন না ... আমার অনুমানটি একটি অভ্যন্তরীণ অবস্থা সিভি 2. রডরিগগুলির সাথে যে কোনওভাবে छेड़छाड़ করা উচিত নয়, তবুও ইন্টারফেসটি পার্শ্ব প্রতিক্রিয়া দ্বারা এই জাতীয় প্রতিরোধের অনুমতি দেয় বলে মনে হচ্ছে ...
জুলিয়েন

এটা সন্দ্বিহান. যদি আমি লুপটি আনরোল করি তবে এটি কার্যকর হবে যখন আমি ফলাফলটি দুটি ভিন্ন ভেরিয়েবলের np.zeros(3)মধ্যে সঞ্চয় করি । যদি আমি ফলাফলটি সংরক্ষণ না করে বা একই পরিবর্তনশীল দু'বার ব্যবহার না করি তবে তা হবে না। আরও অল্প জ্ঞানযুক্ত কেউ এই বিষয়ে কিছুটা আলোকপাত করতে পারেন।
অলস

1
এফওয়াইআই, আমি উইন্ডোজে পাইথন 3 তেও একই জিনিসটি দেখছি ...
জুলিয়েন

উত্তর:


8

এই খুব সম্ভবত একটি uninitialized অ্যারে যেমন দ্বারা ফিরে আসেন np.empty। এটি মেমরি পুনর্ব্যবহারের সাথে একত্রে আপনি যে ধরণের প্রভাব দেখছেন তাতে বাড়ে। একটি সর্বনিম্ন উদাহরণ হবে:

for a in range(5):
    y = np.empty(3,int)
    x = (np.arange(3)+a)**3
    print(x,y)
    del x

# [0 1 8] [94838139529536              0              0]
# [ 1  8 27] [0 1 8]
# [ 8 27 64] [ 1  8 27]
# [ 27  64 125] [ 8 27 64]
# [ 64 125 216] [ 27  64 125]

প্রথম পুনরাবৃত্তিতে কীভাবে yআবর্জনা রয়েছে এবং পর্যায়ক্রমে প্রতিটি পুনরাবৃত্তিতে এটি আগেরটির মান ধারণ করে xকারণ এটির স্মৃতি নির্ধারিত হয়েছে যা ঠিক আগে মুক্তি পেয়েছিল ।

আমরা সহজেই এটি পরীক্ষা করতে পারি যে মূল উদাহরণে এটি tvecআগেরটিও পপ আপ হয়:

def changes():                              
    rmat=np.eye(4)                      
    tvec=np.array([4,0.0,2.5])
    (rvec, jacobian)=cv2.Rodrigues(rmat)
    print(rvec)

for i in range(3):                    
    changes()                               

# [[4.6609787e-310]
#  [0.0000000e+000]
#  [0.0000000e+000]]
# [[4. ]
#  [0. ]
#  [2.5]]
# [[4. ]
#  [0. ]
#  [2.5]]

আমরা আরও অনুমান করতে পারি যে এটির অদ্ভুত পছন্দ rmatযা ত্রুটিটিকে ট্রিগার করে।

এটি সম্ভবত একটি বাগ eye(4) একেবারেই গৃহীত হয়েছে কারণ, আনুষ্ঠানিকভাবে, rmatএটি 3x1 1x3 বা 3x3 হওয়া উচিত। প্রকৃতপক্ষে, 1D এর rmat3 টি উপাদান নেই যা পাইথন মোড়কে সঠিকভাবে প্রত্যাখ্যান করে। আমার সন্দেহ হ'ল পাইথন স্তরে 2D ´rmat`s সঠিকভাবে পরীক্ষা করা হয় না। সি কোডটি ভুল আকারটি সনাক্ত করে ত্রুটি কোডটি ফিরিয়ে দেওয়া ছাড়া কিছুই করে না যা পাইথন কোড যাচাই করে না।

প্রকৃতপক্ষে একটি rmat=eye(3)প্রভাব ব্যবহার চলে যায়:

def changes():
    rmat=np.eye(3)
    tvec=np.array([4,0.0,2.5])
    (rvec, jacobian)=cv2.Rodrigues(rmat)
    print(rvec)

for a in range(3):
    changes()

# [[0.]
#  [0.]
#  [0.]]
# [[0.]
#  [0.]
#  [0.]]
# [[0.]
#  [0.]
#  [0.]]

জন্য np.emptyএই আচরণ সুপরিচিত, কারণ এটি মেমরি লাগে তারা আসতে বাইট, বিদ্যমান মান আপডেট ছাড়া। তবে cv2.Rodriguesফাংশনটি কঠোর গণনার পরে কিছু অর্থবোধক মান ফিরে আসার কথা। তদুপরি, ওপিতে উপস্থাপন করা অদ্ভুত মানগুলি খুব কমই আবর্জনা হিসাবে বিবেচনা করা যেতে পারে, কারণ এগুলি সমস্তই শূন্যের খুব কাছাকাছি।
স্কাইরোকোরিক্স

1
@ সিরোকোরিক্স আপনি কি আমার দ্বিতীয় স্নিপেটটি বেশ জোরালো বলে সম্মত করবেন না?
পল প্যানজার

ইনপুট আকারের জন্য যাচাই করার জন্য আমি জনসংযোগ জমা দিয়েছি ।
ক্যাট্রি

3

অবশ্যই, এটি রডরিগস কার্যক্রমে একটি বাগ ...

আপনি যদি সংশ্লিষ্ট ডকটি পড়েন তবে দেখতে পাবেন যে cv2.Rodriguesএর 2 টি পৃথক ইন্টারফেস রয়েছে:

একটি যা সি ++ ইন্টারফেসের অনুকরণ করে, যেখানে ঘূর্ণন ভেক্টর (এবং alyচ্ছিক জ্যাকোবিয়ান) রেফারেন্স দ্বারা পাস হয় এবং ফাংশনটির মাধ্যমে সংশোধিত হয়

cv2.Rodrigues(src, dst[, jacobian]) --> None

এবং একটি (আরও পাইথোনিক) যেখানে ঘূর্ণন ভেক্টর এবং জ্যাকোবিয়ান টিউপল হিসাবে ফিরে আসে

cv2.Rodrigues(src) --> dst, jacobian

আপনি যদি প্রথম ইন্টারফেস ব্যবহার করেন তবে পিবি অদৃশ্য হয়ে যায় ...

import numpy as np
import cv2

def changes():                              
    rmat=np.eye(4)                      
    tvec=np.zeros(3)
    #(rvec, jacobian)=cv2.Rodrigues(rmat)
    cv2.Rodrigues(rmat, tvec)
    print(tvec)

for i in range(2):                    
    changes()

ফলাফল:

[0. 0. 0.]
[0. 0. 0.]

আরও তদন্তের পরে সম্পাদনা করুন:

প্রত্যাশা অনুযায়ী ফাংশনটি আরও বগী: প্রথম ইন্টারফেস, পরামিতি ব্যবহার করার সময় dstjacobian বগিযুক্ত: এবং কোনও সংশোধন করা হয় না, যা ডকাস্ট্রিংয়ের সাথে সম্পূর্ণ বিপরীতে রয়েছে:

>>> help(cv2.Rodrigues)
Help on built-in function Rodrigues:

Rodrigues(...)
    Rodrigues(src[, dst[, jacobian]]) -> dst, jacobian
    .   @brief Converts a rotation matrix to a rotation vector or vice versa.
    .   
    .   @param src Input rotation vector (3x1 or 1x3) or rotation matrix (3x3).
    .   @param dst Output rotation matrix (3x3) or rotation vector (3x1 or 1x3), respectively.
    .   @param jacobian Optional output Jacobian matrix, 3x9 or 9x3, which is a matrix of partial
    .   derivatives of the output array components with respect to the input array components.

অন্য কথায়, এর জন্য পরিষ্কারভাবে একটি বাগ রিপোর্ট দরকার ...


অন্যান্য উত্তর সঠিক। সমস্যা থেকে আসে np.eye(4)। পদ্ধতিটির জন্য (3x1 বা 1x3) রোটেশন ভেক্টর বা (3x3) রোটেশন ম্যাট্রিক্স প্রয়োজন। এখানে এনপি.ই (4) দিয়ে ফাংশনটি কিছু আকারের সাথে ডিএসটি তৈরি করে। কিন্তু যেহেতু ইনপুট আকারটি ভুল, পদ্ধতিটি কিছুই করে না এবং এটি একীকরণ করে। এছাড়াও, আপনি ওপেনসিভির একটি অপ্রচলিত সংস্করণটির দিকে ইশারা করছেন। মাস্টার সংস্করণ ব্যবহার করা বা একটি নির্দিষ্ট সংস্করণে নির্দেশ করা আরও ভাল: ডকস.ওপেনসিভি.আর
ক্যাট্রি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.