ysf*_*rky 5 python opencv image-processing computer-vision image-stitching
我有一个带有带有广角镜头的固定相机和移动物体的系统。当物体匀速移动时,我以 10 毫米间隔和 2064x40 像素拍摄图像。此外,我在没有匀速的情况下拍摄了 2048x40 的图像。我想缝合这些捕获的图像。
\n首先我参考链接尝试了OpenCV的拼接方法。但是,我收到错误代码 1,并且我了解到两个图像之间没有足够的重叠区域来缝合。
\n之后,我想我可以尝试连接恒速物体的图像。我使用了下面的代码,并将 13 px 作为移位参数。
\nimport numpy as np\nimport cv2\nimport os\n\nfrom Stitching.Blending import UVSSBlendingConcate\nfrom Stitching.DistortionCorrection import load_coefficients\n\n\ndef load_images_from_folder(folder):\n print("\\nImages are reading from folder: " + folder)\n images = []\n for filename in os.listdir(folder):\n img = cv2.imread((folder + "/" + filename))\n if img is not None:\n images.append(img)\n return images\n\n\ndef unDistortImages(images):\n mtx, dist = load_coefficients(\'calibration_chessboard.yml\')\n for i in range(len(images)):\n images[i] = cv2.undistort(images[i], mtx, dist, None, None)\n return images\n\n\ndef LineTriggerConcate(dx, images, blending, IsFlip, IsUnDistorted):\n print("\\nImage LineTrigger Concate Start")\n\n if IsUnDistorted:\n images = unDistortImages(images)\n\n cropped_images = []\n for i in range(len(images) - 1):\n if IsFlip is True:\n cropped_images.append(cv2.flip(images[i][2:2 + dx, 0:2064], 0))\n else:\n cropped_images.append(images[i][2:2 + dx, 0:2064])\n\n if not blending:\n result = cv2.vconcat(cropped_images)\n return result\n else:\n global blendingResult\n for i in range(len(cropped_images) - 1):\n if i == 0:\n blendingResult = UVSSBlendingConcate(cropped_images[i], cropped_images[i + 1], dx / 2)\n else:\n blendingResult = UVSSBlendingConcate(blendingResult, cropped_images[i + 1], dx / 2)\n\n print("\\nImage LineTrigger Concate Finish")\n return blendingResult\n\n\ndef concateImages(image_list):\n image_h = cv2.vconcat(image_list)\n return image_h\n\n\ndef main():\n images_path = "10mm"\n image_list = load_images_from_folder(images_path)\n\n # LineTriggerConcate Parameters\n shiftParameter = 13\n IsBlending = False\n IsFlipped = True\n IsUnDistorted = False\n result = LineTriggerConcate(shiftParameter, image_list, IsBlending, IsFlipped, IsUnDistorted)\n\n cv2.imwrite(images_path + r"//" + str(shiftParameter) + r"_Shift_" + str(IsBlending) + "_Blending_Result.bmp", result)\n print(\'Successfully saved to %s\' % images_path)\n\n\nif __name__ == \'__main__\':\n main()\nRun Code Online (Sandbox Code Playgroud)\n在上面的结果中,过渡不平滑,我尝试使用混合和不失真方法来修复过渡,但没有成功。
\n另一方面,我假设物体的速度是恒定的,但不幸的是在实际情况中它不是\xe2\x80\x99t。当物体有加速度时,图像的某些部分可能会被拉长或缩短。
\n有人可以建议任何方法或研究吗?
\n我还分享了部分10mm间隔的数据集。
您当前的解决方案似乎非常接近我。您是否尝试过在合并之前使用 min diff 来清理最后一点对齐?基本上创建某种形式的值函数(可以是逐像素颜色距离的总和)。您可以将此值函数应用于图像中的单条线、多条线或随机分散的点。但然后在与辅助图像进行比较时逐步步进单个像素。
下面是一些代码(c++ 中的 sry)演示了此方法的简单实现(请注意,这只是为了与可变速度对齐,并且不会纠正需要模糊的硬边缘):
#include <stdio.h>
#include <opencv2/opencv.hpp>
#include <Windows.h>
#include <string>
using namespace cv;
int main(int argc, char** argv)
{
int compareHeight = 2;
Mat image;
bool firstLoop = true;
for (int i = 140; i >=53; i--) //140
{
std::string fileName = "C:/Users/thoma/Downloads/stitching-main/stitching-main/dataset_10mm/"+std::to_string(i) + ".bmp";
Mat tempImage;
tempImage = imread(fileName, 1);
std::cout << "imsize: " << tempImage.rows << std::endl;
if (firstLoop) { image = tempImage; firstLoop = false; }
else
{
double lowestNorm = -1;
int index = -1;
Mat refSlice = image(Rect(0, image.rows- compareHeight, image.cols, compareHeight));
for (int ii = 0; ii < tempImage.rows- compareHeight; ii++)
{
Mat testSlice = tempImage(Rect(0, ii, tempImage.cols, compareHeight));
double tempNorm = cv::norm(refSlice, testSlice);
if (lowestNorm == -1)
{
lowestNorm = tempNorm;
index = ii;
}
else if (tempNorm < lowestNorm)
{
lowestNorm = tempNorm;
index = ii;
}
}
std::cout << index << " , "<<lowestNorm<< std::endl;
index+=compareHeight;
if (tempImage.rows - index < 1) { std::cout << "skipped" << std::endl; continue; }
Mat crop_img = tempImage(Rect(0, index, tempImage.cols, tempImage.rows-index));
vconcat(image, crop_img, image);
}
}
if (!image.data)
{
printf("No image data \n"); system("pause");
return -1;
}
namedWindow("Display Image", WINDOW_AUTOSIZE);
imshow("Display Image", image);
waitKey(0);
system("pause");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在示例集上运行上面的代码: https ://i.stack.imgur.com/14bXq.jpg
关于您的数据集的一些附加说明:我注意到仍然存在一些扭曲,因此通过在图像的特定条带上执行此拟合,您可以比其他功能更喜欢某些功能。另外,我每次计算使用 2 行来尝试阻止行走,您可以使用更多或更少。最后,从图像中剪掉前几行可能会有所帮助,因为图像边缘似乎有一些可变的照明。稍后我可能会花更多时间在这方面,但这就是我现在使用您当前的数据集的地方。