我有一個帶有廣角鏡頭的固定攝像機和一個移動物體的系統。當物體以恒定的速度移動時,我捕捉到了間隔為10毫米、像素為2064x40的影像。此外,我還捕獲了2048x40的影像,但沒有恒定速度。我想把這些捕捉到的影像進行拼接。
首先,我參照鏈接嘗試了OpenCV的拼接方法。然而,我得到了錯誤代碼1,我了解到兩個影像之間沒有足夠的重疊區域來縫合。
之后,我想我可以嘗試將恒速物體的影像連接起來。我使用了下面的代碼,我把13px作為移動引數。
我所嘗試的代碼:
import numpy as np
import cv2
import os
from Stitching.Blending import UVSSBlendingConcate
from Stitching.DistortionCorrection import load_coefficients
def load_images_from_folder(folder)。
print("
影像正在從檔案夾中讀取。" folder)
影像 = []
for filename in os.listdir(Folder):
img = cv2.imread((folder "/"/span> filename))
if img is not None:
images.append(img)
return images
def unDistortImages(images)。
mtx, dist = load_coefficients('calibration_chessboard.yml')
for i in range(len(images))。
images[i] = cv2.undistort(images[i], mtx, dist, None, None)
return 影像
def LineTriggerConcate(dx, images, blending, IsFlip, IsUnDistorted)。
print("
Image LineTrigger Concate Start")
if IsUnDistorted:
images = unDistortImages(images)
cropped_images = []
for i in range(len(images) - 1) 。
if IsFlip is True:
cropped_images.append(cv2. flip(images[i][2:2 dx, 0:2064], 0)
else:
cropped_images.append(images[i][2:2 dx, 0:2064] )
if not blending:
結果 = cv2.vconcat(cropped_images)
return result
else:
global blendingResult
for i in range(len(cropped_images) - 1) 。
if i == 0:
blendingResult = UVSSBlendingConcate(cropped_images[i], cropped_images[i 1], dx / 2)
else:
blendingResult = UVSSBlendingConcate(blendingResult, cropped_images[i 1], dx / 2)
print("
Image LineTrigger Concate Finish")
return blendingResult
def concateImages(image_list)。
image_h = cv2.vconcat(image_list)
return image_h
def main()。
images_path = "10mm"/span>
image_list = load_images_from_folder(images_path)
# LineTriggerConcate引數
shiftParameter =13
IsBlending = False[/span]。
IsFlipped = True
IsUnDistorted = False[/span
result = LineTriggerConcate(shiftParameter, image_list, IsBlending, IsFlipped, IsUnDistorted)
cv2. imwrite(images_path r"//" str(shiftParameter) r"_Shift_" str(IsBlending) "_Blending_Result. bmp", result)
print('Successfully saved to %s' % images_path)
if __name__ == '__main__'/span>:
main()
輸出影像:
在上述結果中,過渡并不平滑,我試圖通過使用混合和不失真方法來修復過渡,但我并不成功。
另一方面,我假設物體的速度是恒定的,但不幸的是,在實際情況中并不是這樣。當物體有加速度時,影像的某些部分可能被拉長或縮短。
誰能告訴我們任何方法或研究嗎? 我還分享了一部分10mm間隔的資料集。
uj5u.com熱心網友回復:
這里是一個有點 "形態豐富 "的解決方案:
將影像轉換為邊緣稀釋邊緣
稀釋邊緣(以提高漸變的靈活性)
-找到每個影像的最佳匹配偏移量到累積影像的底部-存盤偏移量并追加累積影像-重建完整的影像。
使用RGB影像和存盤的偏移量重建完整的影像
。#include <stdio.h>/span>
#include <opencv2/opencv.hpp>
#include <Windows.h>
#include <string>
using namespace cv;
double imDiff(Mat mat1, Mat mat2)
{
double sumSquares = 0;
Mat channels1[3], channels2[3] 。
cv::split(mat1, channels1);
cv::split(mat2, channels2)。
Mat dif1 = channels1[0] - channels2[0] 。
Mat dif2 = channels1[1] - channels2[1] 。
Mat dif3 = channels1[2] - channels2[2] 。
dif1.mul(dif1)。
dif2.mul(dif2);
dif3.mul(dif3)。
sumSquares = cv::sum(dif1)[0] cv:: sum(dif2)[0] cv::sum(dif3) [0] 。
return sumSquares。
}
Mat autoCanny(Mat image)
{
Mat edged;
cv::Canny(image, edged,75,125) 。
墊子模糊了。
int dilation_size = 1;
Mat element = cv::getStructuringElement(MORPH_CROSS,
Size(2 * dilation_size 1, 2 * dilation_size 1) 。
Point(dilation_size, dilation_size))。
cv::dilate(edged, blurred, element,cv::Point(-1,-1), 2)。
//cv::GaussianBlur(edged, blurred, cv::Size(5, 5), 0) 。
return blurred。
}
int main(int argc, char** argv)
{
int compareHeight = 25;
int compareWidth = 350;
std::vector<int> offsets = std::vector<int>()。
矩陣影像。
bool firstLoop = true;
for (int i = 140; i > =53; i--) //140; i >=53; i--
{
std::string fileName = "C:/Users/thoma/Downloads/stitching-main/stitching-main/dataset_10mm/" std::to_string(i) " .bmp"。
Mat tempImage = imread(fileName, 1)。
tempImage = autoCanny(tempImage);
//std::cout << "imsize: " << tempImage.rows << std::endl;
if (firstLoop) { image = tempImage; firstLoop = false; }
else(firstLoop) { image = tempImage; firstLoop = false; }
{
double lowestNorm = -1;
int index = -1;
Mat refSlice = image(Rect(image.cols/2-compareWidth, image.rows- compareHeight, 2*compareWidth, compareHeight) )。
for (int ii = 0; ii < tempImage.rows- compareHeight; ii )
{
Mat testSlice = tempImage(Rect(tempImage.cols/2-compareWidth, ii, 2*compareWidth, compareHeight) )。
//double tempNorm = cv::norm(refSlice, testSlice);
double tempNorm = imDiff(refSlice, testSlice);
//std::cout << "norm: " << tempNorm << std::endl;
//std::cout << "cust: " << imDiff(refSlice, testSlice) << std::endl;
if ( lowestNorm == -1)
{
lowestNorm = tempNorm;
index = ii;
}
else if (tempNorm < lowestNorm)
{
lowestNorm = tempNorm;
index = ii;
}
}
index = compareHeight;
std::cout << tempImage.rows - index << std::endl;
if (tempImage.rows - index < 1) { std::cout << "skipped" < std::endl; continue; }
//index = 32;
offsets.push_back(index);
Mat crop_img = tempImage(Rect(0, index, tempImage.cols, tempImage.rows-index)) 。
vconcat(image, crop_img, image)。
}
}
namedWindow("Display Image", WINDOW_AUTOSIZE) 。
imshow("Display Image", image)。
waitKey(0)。
firstLoop = true;
int offsetIndex = 0;
for (int i = 140; i >=53; i--) //140; i >=53; i--
{
std::string fileName = "C:/Users/thoma/Downloads/stitching-main/stitching-main/dataset_10mm/" std::to_string(i) ".bmp"。
Mat tempImage = imread(fileName, 1)。
if (firstLoop) { image = tempImage; firstLoop = false; }
else (firstLoop) { images = tempImage; firstLoop = false; }
{
Mat crop_img = tempImage(Rect(0, offsets[offsetIndex], tempImage.cols, tempImage.rows - offsets[offsetIndex])。
vconcat(image, crop_img, image);
offsetIndex ;
}
}
namedWindow("顯示影像", WINDOW_AUTOSIZE)。
imshow("Display Image", image)。
waitKey(0)。
system("pause")。
return 0;
結果圖片。 https://imgur.com/9dEXonn
注意。 這個方法使用圖片的中心條紋。 在影像上似乎仍有非微不足道的失真,向邊緣增加,所以這個方法試圖忽略這一點。 這種方法容易受到缺乏水平邊緣的影響(很確定大多數縫合方法都會如此)。 這個策略(正如我所寫的那樣)有很多 "神奇的變數",也就是說,如果你打算部署這段代碼或以自動化的方式運行它,你會希望撥入或自動化。
uj5u.com熱心網友回復:
你目前的解決方案對我來說似乎非常接近。 你是否嘗試過使用min diff來清理合并前的最后一點排列? 基本上創建某種形式的值函式(可以是逐個像素的顏色距離的總和)。你可以將這個值函式應用于影像中的一條線、幾條線或隨機散布的點。 但是,在與第二張影像進行比較時,要按單個像素逐步進行。
這里有一些代碼(抱歉,是用C 撰寫的),演示了這個的簡單實作(注意,這只是為了以可變的速度對齊,對于需要模糊的硬邊緣的修正沒有任何作用):
#include <stdio.h>
#include <opencv2/opencv.hpp>
#include <Windows.h>
#include <string>
使用名稱空間cv。
int main(int argc, char** argv)
{
int compareHeight = 2;
矩陣影像。
bool firstLoop = true;
for (int i = 140; i > =53; i--) //140; i >=53; i--
{
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(firstLoop) { image = tempImage; firstLoop = false; }
{
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("沒有影像資料
"); system("pause");
return -1。
}
namedWindow("顯示影像", WINDOW_AUTOSIZE)。
imshow("Display Image", image)。
waitKey(0)。
system("pause")。
return 0;
在你的例子集上運行上述代碼。 https://imgur.com/EYvJT8I
關于你的資料集的一些補充說明。 我注意到仍然有一些扭曲,所以通過對影像的特定條帶進行這種擬合,你可以對一些特征比其他特征更有利。 另外,我在每次計算時使用2行,以試圖防止走樣,你可以使用更多或更少。 最后,將影像的前幾行剪掉可能會有幫助,因為在影像的邊緣似乎有一些可變的照明。 我以后可能會花更多的時間來研究這個問題,但這是我現在對你目前的資料集的看法。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/311674.html
標籤:
上一篇:在谷歌網站上添加有動態資料的地圖
