В настоящее время я работаю над камерой, которая имеет «рыбий глаз» (которая невелика, но все же), и я пытаюсь ее не искажать.
Как стартер: я не настолько знаком с opencv, Я как всегда на документации, пытаясь сделать что-нибудь. (и / или здесь ищите ответ на мою проблему (проблемы)).
Так что я видел несколько примеров в Интернете, я попробовал решения и получил некоторые результаты с моей стороны.
Здесь что я нашел:
DIM=(1094, 729)
K=np.array([
[1307.2807020496643, 0.0, 530.3754311563506],
[0.0, 1318.342691460933, 354.98352268131123],
[0.0, 0.0, 1.0]
])
D=np.array([
[-0.2994762856767568],
[0.5036082961388784],
[-4.231072729639434],
[3.8646397788794578]
])
def undistort(img_path):
img = cv2.imread(img_path)
h,w = img.shape[:2]
print(K)
print(D)
print(np.eye(3))
print(DIM)
map1, map2 = cv2.fisheye.initUndistortRectifyMap(K, D, np.eye(3), K, DIM, cv2.CV_16SC2)
undistorted_img = cv2.remap(img, map1, map2, interpolation=cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT)
cv2.imshow("undistorted", undistorted_img)
cv2.imwrite("test.jpg", undistorted_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
if __name__ == '__main__':
for p in sys.argv[1:]:
undistort(p)
Это сценарий python, который я использую, чтобы не искажать изображение. Данные вверху (K & D) генерируются с помощью другого скрипта. Я не упоминал об этом, потому что у меня есть перевод в C ++, который показывает тот же результат для того же base_picture
И для этой функции, если я даю искаженное изображение, например: Я получил этот результат:
Итак, я вижу, что крошечные искажения были устранены.
Но когда я пытаюсь реализовать эту же функцию в C ++, выполните следующие действия:
src = cv::imread(“path/to/image.jpg");
cv::Size size = {src.cols, src.rows};
cv::Mat K(3, 3, cv::DataType<double>::type);
K.at<double>(0, 0) = 1307.2807020496643;
K.at<double>(0, 1) = 0.0;
K.at<double>(0, 2) = 530.3754311563506;
K.at<double>(1, 0) = 0.0;
K.at<double>(1, 1) = 1318.342691460933;
K.at<double>(1, 2) = 354.98352268131123;
K.at<double>(2, 0) = 0.0;
K.at<double>(2, 1) = 0.0;
K.at<double>(2, 2) = 1.0;
cv::Mat D(4, 1, cv::DataType<double>::type);
D.at<double>(0, 0) = -0.2994762856767568;
D.at<double>(1, 0) = 0.5036082961388784;
D.at<double>(2, 0) = -4.231072729639434;
D.at<double>(3, 0) = 3.8646397788794578;
cv::Mat E = cv::Mat::eye(3, 3, cv::DataType<double>::type);
cv::Mat map1;
cv::Mat map2;
std::cout << K << std::endl;
std::cout << D << std::endl;
std::cout << E << std::endl;
std::cout << size << std::endl;
cv::initUndistortRectifyMap(K, D, E, K, size, CV_16SC2, map1, map2);
cv::Mat undistort;
cv::remap(src, undistort, map1, map2, CV_INTER_LINEAR,
CV_HAL_BORDER_CONSTANT);
Базовое изображение остается прежним, НО я получил это в результате:
И, как вы можете сказать, все пошло хуже ...
Я сбросил K, D & E в моем скрипте python и программе на c ++ (оба дают один и тот же результат для одной и той же базовой картинки) (я имею в виду, когда вычисляю данные)
Это идет не так от initUndistortRectifyMap вплоть до переназначения и, наконец, imshow совсем не то, что я ожидал.
Я пытаюсь вывести map1 & map2 в программу python script & C ++ (не просматривал ВСЕ данные) и я мог заметить, что в конце одной из карт (не смотрел обе) ults были разными.
Поскольку я вызываю функцию, используя один и тот же параметр (насколько мне известно), я ожидал, что карта будет одинаковой для обеих программ.
Есть ли что-то Я делаю не так? Как возиться с типами или чем-то еще?
Изменится ли что-нибудь для вычисления изображения из cv :: imread или из захвата кадра с камеры?
(Просто чтобы вы знали, кадр (.jpg), с помощью которого производятся вычисления, является cv :: imwrite из захвата кадра камеры, тогда я намерен больше не использовать изображения, а только работать с cv :: Mat, заполненным данными из захвата камеры.)
(я знаю, что в конце перечисления не совпадают, но даже с использованием cv::BORDER_CONSTANT
у меня все еще та же проблема.)