許多方法可以將HTML元素與CSS對齊,但是一起使用或單獨使用它們并不是那么容易。開發人員所面臨的困難之一就是試圖將元素集中在頁面中間。
因此,在本文中,我將展示一些最常用的方法,即通過使用不同的CSS屬性在水平和垂直方向上居中圖像。
讓我們開始使用3個不同的CSS屬性將圖像水平居中。
使圖像水平居中的第一種方法是使用text-align屬性。但是,僅當圖像位于塊級容器(例如<div>)內時,此方法才有效:
使圖像居中的另一種方法是使用margin:auto屬性(用于左邊距和右邊距)。但是,單獨使用margin:Auto將不適用于圖像。如果需要使用margin:auto,則還必須使用2個其他屬性。
margin-auto屬性對內聯級別的元素沒有任何影響。由于<img>標簽是一個內聯元素,因此我們需要先將其轉換為塊級元素:
其次,我們還需要定義寬度。因此,左右邊緣可以占用其余的空白空間并自動對齊,可以這樣解決問題(除非我們給出100%的寬度):
將圖像水平居中的第三種方法是使用display:flex。同樣,我們對容器使用text-align屬性,它也會使用display:flex。但是,僅使用display:flex是不夠的。容器還必須具有一個稱為justify-content的附加屬性。
justify-content屬性與display:flex一起使用,我們可以使用它水平放置圖像的中心。最后,圖像的寬度必須小于容器的寬度,否則,它會占用100%的空間,然后我們就無法對其進行集中化。
1、Display: Flex
對于垂直對齊,使用display:flex確實很有幫助??紤]到我們的容器的高度為800px,但圖像的高度僅為500px:
現在,在這種情況下,向容器中添加一行代碼(align-items:center)就可以了:
如果將align-items屬性與display:flex一起使用,就會將元素垂直放置。
2、位置:絕對和變換屬性
垂直對齊的另一種方法是一起使用position和transform屬性。這個有點復雜,所以讓我們一步一步地做。
步驟1:定義絕對位置
首先,我們將圖像的定位行為從靜態更改為絕對:
同樣,它應該位于相對放置的容器內,因此我們添加一個位置:相對于其容器的div。
步驟2:定義頂部和左側屬性
其次,我們定義圖像的頂部和左側屬性,并設置為50%。這會將圖像的起點(左上角)移到容器的中心:
步驟3:定義變換屬性
在第二步的時候已經將圖像的一部分移出容器。因此,我們需要將其取回內部。在圖像上定義轉換屬性,并在其X和Y軸上添加負50%可以達到目的:
還可以使用其他方法進行水平和垂直居中,我這里只嘗試了最常用的方法。希望這篇文章可以幫助你了解如何在頁面中心對齊圖像。
初學css的新手朋友經常會遇到一個問題,當文字和圖片出現在同一行或者同一個div里面的時候,在瀏覽器中運行出來的顯示效果往往是在不同的行,那么我們怎么才能在css中控制他們在同一行顯示呢,其實方法有3種:1、通過添加css的“vertical-align:middle;”;2、如果圖片是背景圖片,可以在css中設置背景圖片,然后設置文字的padding屬性;3、把文字和圖片分別放入不同的div中。上面三種方法都可以讓圖片和文字在同一行顯示,下面我們用實例來應用一下。
1、在css中給div添加上“vertical-align:middle”屬性
我們用“注冊、登陸、找回密碼”這個在實際運用中經常遇到的情況還做實例,把“注冊”和“登陸”做成圖片,“找回密碼”設置成文字其html代碼如下:
使用css的“vertical-align:middle”屬性讓圖片和文字在同一行對齊是一種非常常用的方法,希望大家可以掌握。
2、把圖片設置為背景圖片
如果我們的圖片本身是一個背景圖片的話,可以在css中使用“background”來設置該圖片,然后設置文字的padding屬性就可以使他們在同一行顯示了,html代碼如下:
我們在css中設置了背景圖片,然后又設置了文字的padding-left屬性,這樣,圖片和文字就在同一行顯示了,運行結果就不切圖了,你可以自己試一下。
3、下面說下最后一種方法,分別把圖片和文字放入不同的div中,然后用“margin”屬性進行定位,就可以使他們顯示在同一行了,html代碼如下:
代碼如下:
css代碼如下:
代碼如下:
在瀏覽器中運行以后,你會發現,這個方法也可以讓圖片和文字在同一行顯示,但是看起來好像麻煩了一點,所以個人還是比較推薦第一種方法的。
學習Java的同學注意了?。?!
學習過程中遇到什么問題或者想獲取學習資源的話,歡迎加入Java學習交流,裙號碼:253772578【長按復制】 我們一起學Java!
在這篇文章中,我們將學習如何使用OpenCV執行基于特征的圖像對齊。我們將使用移動電話拍攝的表格的照片與表格的模板對齊。我們將使用的技術通常被稱為“基于特征圖像對齊”,因為在該技術中,在一個圖像中檢測稀疏的特征集并且在另一圖像中進行特征匹配。然后基于這些匹配特征將原圖像映射到另一個圖像,實現圖像對齊。如下圖所示:
添加圖片注釋,不超過 140 字(可選)
在許多應用程序中,我們有兩個相同場景或同一文檔的圖像,但它們沒有對齊。換句話說,如果您在一個圖像上選擇一個特征(例如白紙的一個邊角),則另一個圖像中同一個邊角的坐標會有很大差異。圖像對齊(也稱為圖像配準)是使一個圖像(或兩個圖像)進行變換的方法,使得兩個圖像中的特征完美地對齊。入戲
下面是一個例子,中間的表是手機拍攝的表格,左邊的表是原始文檔。中間的表在經過圖像對齊技術處理之后結果如右圖所示,可以和左邊的模板一樣。對齊之后就可以根據模板的格式對用戶填寫的內容進行分析了。
添加圖片注釋,不超過 140 字(可選)
圖像對齊有許多應用。
在許多文檔處理應用程序中,第一步是將掃描或拍攝的文檔與模板對齊。例如,如果要編寫自動表單閱讀器,最好先將表單與其模板對齊,然后根據模板中的固定位置讀取字段。
在一些醫學應用中,可以把多次拍攝的照片拼接起來。
圖像對齊最有趣的應用可能是創建全景圖。在這種情況下,兩個圖像不是平面的圖像而是3D場景的圖像。通常,3D對齊需要深度信息。然而,當通過圍繞其光軸旋轉相機拍攝兩個圖像時(如全景圖的情況),我們可以使用本教程中描述的技術來對齊全景圖的兩張圖像。
圖像對齊技術的核心是一個簡單的3×3矩陣,稱為Homography(單應性變換)。具體見:
https://blog.csdn.net/LuohenYJ/article/details/89334249
https://en.wikipedia.org/wiki/Homography
https://mp.weixin.qq.com/s/-XrjAjf8ItNMkQyqvcjATQ
我們來看看用法。
C ++
findHomography(points1, points2, h)
python
h, status = cv2.findHomography(points1, points2)
其中,points1和points2是矢量/對應點的陣列,以及?是單應性矩陣。
在許多計算機視覺應用中,我們經常需要識別圖像中有趣的穩定點。這些點稱為關鍵點或特征點。在OpenCV中實現了幾個關鍵點檢測器(例如SIFT,SURF和ORB)。在本教程中,我們將使用ORB特征檢測器,因為SIFT和SURF已獲得專利,如果您想在實際應用中使用它,則需要支付許可費。ORB快速,準確且無許可證!ORB關鍵點使用圓圈顯示在下圖中。
添加圖片注釋,不超過 140 字(可選)
ORB代表Oriented FAST和Rotated BRIEF;讓我們看看FAST和BRIEF是什么意思。
特征點檢測器有兩個部分
(1) 定位器
識別圖像上在圖像變換下穩定不變的點,如平移(移位),縮放(增大/減?。┖托D。定位器找到這些點的x,y坐標。ORB檢測器使用的定位器稱為FAST。詳細信息見:
https://docs.opencv.org/3.0-beta/doc/py_tutorials/py_feature2d/py_fast/py_fast.html
(2) 特征描述子
上述步驟中的定位器只能告訴我們有趣的點在哪里。特征檢測器的第二部分是特征描述子,它對點的外觀進行編碼,以便我們可以分辨不同的特征點。在特征點評估的特征描述只是一個數字數組。理想情況下,兩個圖像中的相同物理點應具有相同的特征描述。ORB使用名為BRISK的特征描述子。詳細信息見:
https://www.robots.ox.ac.uk/~vgg/rg/papers/brisk.pdf
定位器和特征描述子應用很廣泛。計算機視覺的許多應用中,我們分兩步解決識別問題a)定位;2)識別。例如,為了實現面部識別系統,我們首先需要一個面部檢測器,其輸出面部所在矩形的坐標。檢測器不知道或不關心該人是誰。唯一的工作就是找到一張臉。系統的第二部分是識別算法。原始圖像被裁剪為檢測到的面部矩形,并且該裁剪的圖像反饋送到最終識別該人的面部識別算法。特征檢測器的定位器就像面部檢測器。描述子類似識別器。
只有當我們知道兩個圖像中的對應特征時,才能計算出與兩個圖像相關的單應性。因此,使用匹配算法來查找一個圖像中的哪些特征與另一圖像中的特征匹配。為此,將一個圖像中的每個特征的描述子與第二個圖像中的每個特征的描述子進行比較,以找到良好的匹配點。也就是說我們可以通過描述子找到要匹配的特征點,然后根據這些匹配的特征點,計算兩個圖像相關的單應性,實現圖像映射。
ORB其他信息可以見
https://www.jianshu.com/p/387b8ac04c94
現在我們可以總結圖像對齊所涉及的步驟。
Step1讀圖
我們首先在C ++中和Python中讀取參考圖像(或模板圖像)和我們想要與此模板對齊的圖像。
Step2尋找特征點
我們檢測兩個圖像中的ORB特征。雖然我們只需要4個特征來計算單應性,但通常在兩個圖像中檢測到數百個特征。我們使用Python和C ++代碼中的參數MAX_FEATURES來控制功能的數量。
Step3 特征點匹配
我們在兩個圖像中找到匹配的特征,按匹配的評分對它們進行排序,并保留一小部分原始匹配。我們使用漢明距離(hamming distance)作為兩個特征描述符之間相似性的度量。請注意,我們有許多不正確的匹配。
Step4 計算Homography
當我們在兩個圖像中有4個或更多對應點時,可以計算單應性。上一節中介紹的自動功能匹配并不總能產生100%準確的匹配。20-30%的比賽不正確并不罕見。幸運的是,findHomography方法利用稱為隨機抽樣一致性算法(RANSAC)的強大估計技術,即使在存在大量不良匹配的情況下也能產生正確的結果。RANSAC具體介紹見:
https://www.cnblogs.com/xingshansi/p/6763668.html
https://blog.csdn.net/zinnc/article/details/52319716
Step5 圖像映射
一旦計算出準確的單應性,我可以應用于一個圖像中的所有像素,以將其映射到另一個圖像。這是使用OpenCV中的warpPerspective函數完成的。
在本節中,我們將使用OpenCV呈現用于圖像對齊的C++和Python代碼。所處理的對象為對本文第二張圖所示的三張圖。其中第一張圖為參考圖像,第二張圖為用于對齊的圖,第三張圖為結果圖像。第一張圖和第二張圖特征點匹配的結果如下圖所示:
添加圖片注釋,不超過 140 字(可選)
所有代碼見:
https://github.com/luohenyueji/OpenCV-Practical-Exercise
C++代碼如下:
// OpenCV_Align.cpp : 此文件包含 "main" 函數。程序執行將在此處開始并結束。
//
#include "pch.h"
#include <iostream>
#include <opencv2/opencv.hpp>
#include "opencv2/xfeatures2d.hpp"
#include "opencv2/features2d.hpp"
using namespace std;
using namespace cv;
using namespace cv::xfeatures2d;
//最大特征點數
const int MAX_FEATURES = 500;
//好的特征點數
const float GOOD_MATCH_PERCENT = 0.15f;
/**
* @brief 圖像對齊
*
* @param im1 對齊圖像
* @param im2 模板圖像
* @param im1Reg 輸出圖像
* @param h
*/
void alignImages(Mat &im1, Mat &im2, Mat &im1Reg, Mat &h)
{
// Convert images to grayscale
Mat im1Gray, im2Gray;
//轉換為灰度圖
cvtColor(im1, im1Gray, CV_BGR2GRAY);
cvtColor(im2, im2Gray, CV_BGR2GRAY);
// Variables to store keypoints and descriptors
//關鍵點
std::vector<KeyPoint> keypoints1, keypoints2;
//特征描述符
Mat descriptors1, descriptors2;
// Detect ORB features and compute descriptors. 計算ORB特征和描述子
Ptr<Feature2D> orb = ORB::create(MAX_FEATURES);
orb->detectAndCompute(im1Gray, Mat(), keypoints1, descriptors1);
orb->detectAndCompute(im2Gray, Mat(), keypoints2, descriptors2);
// Match features. 特征點匹配
std::vector<DMatch> matches;
//漢明距離進行特征點匹配
Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create("BruteForce-Hamming");
matcher->match(descriptors1, descriptors2, matches, Mat());
// Sort matches by score 按照特征點匹配結果從優到差排列
std::sort(matches.begin(), matches.end());
// Remove not so good matches 移除不好的特征點
const int numGoodMatches = matches.size() * GOOD_MATCH_PERCENT;
matches.erase(matches.begin() + numGoodMatches, matches.end());
// Draw top matches
Mat imMatches;
//畫出特征點匹配圖
drawMatches(im1, keypoints1, im2, keypoints2, matches, imMatches);
imwrite("matches.jpg", imMatches);
// Extract location of good matches
std::vector<Point2f> points1, points2;
//保存對應點
for (size_t i = 0; i < matches.size(); i++)
{
//queryIdx是對齊圖像的描述子和特征點的下標。
points1.push_back(keypoints1[matches[i].queryIdx].pt);
//queryIdx是是樣本圖像的描述子和特征點的下標。
points2.push_back(keypoints2[matches[i].trainIdx].pt);
}
// Find homography 計算Homography,RANSAC隨機抽樣一致性算法
h = findHomography(points1, points2, RANSAC);
// Use homography to warp image 映射
warpPerspective(im1, im1Reg, h, im2.size());
}
int main()
{
// Read reference image 讀取參考圖像
string refFilename("./image/form.jpg");
cout << "Reading reference image : " << refFilename << endl;
Mat imReference = imread(refFilename);
// Read image to be aligned 讀取對準圖像
string imFilename("./image/scanned-form.jpg");
cout << "Reading image to align : " << imFilename << endl;
Mat im = imread(imFilename);
// Registered image will be resotred in imReg.
// The estimated homography will be stored in h.
//結果圖像,單應性矩陣
Mat imReg, h;
// Align images
cout << "Aligning images ..." << endl;
alignImages(im, imReference, imReg, h);
// Write aligned image to disk.
string outFilename("aligned.jpg");
cout << "Saving aligned image : " << outFilename << endl;
imwrite(outFilename, imReg);
// Print estimated homography
cout << "Estimated homography : \n" << h << endl;
return 0;
}
Python代碼如下:
from __future__ import print_function
import cv2
import numpy as np
MAX_MATCHES = 500
GOOD_MATCH_PERCENT = 0.15
def alignImages(im1, im2):
# Convert images to grayscale
im1Gray = cv2.cvtColor(im1, cv2.COLOR_BGR2GRAY)
im2Gray = cv2.cvtColor(im2, cv2.COLOR_BGR2GRAY)
# Detect ORB features and compute descriptors.
orb = cv2.ORB_create(MAX_MATCHES)
keypoints1, descriptors1 = orb.detectAndCompute(im1Gray, None)
keypoints2, descriptors2 = orb.detectAndCompute(im2Gray, None)
# Match features.
matcher = cv2.DescriptorMatcher_create(cv2.DESCRIPTOR_MATCHER_BRUTEFORCE_HAMMING)
matches = matcher.match(descriptors1, descriptors2, None)
# Sort matches by score
matches.sort(key=lambda x: x.distance, reverse=False)
# Remove not so good matches
numGoodMatches = int(len(matches) * GOOD_MATCH_PERCENT)
matches = matches[:numGoodMatches]
# Draw top matches
imMatches = cv2.drawMatches(im1, keypoints1, im2, keypoints2, matches, None)
cv2.imwrite("matches.jpg", imMatches)
# Extract location of good matches
points1 = np.zeros((len(matches), 2), dtype=np.float32)
points2 = np.zeros((len(matches), 2), dtype=np.float32)
for i, match in enumerate(matches):
points1[i, :] = keypoints1[match.queryIdx].pt
points2[i, :] = keypoints2[match.trainIdx].pt
# Find homography
h, mask = cv2.findHomography(points1, points2, cv2.RANSAC)
# Use homography
height, width, channels = im2.shape
im1Reg = cv2.warpPerspective(im1, h, (width, height))
return im1Reg, h
if __name__ == '__main__':
# Read reference image
refFilename = "./image/form.jpg"
print("Reading reference image : ", refFilename)
imReference = cv2.imread(refFilename, cv2.IMREAD_COLOR)
# Read image to be aligned
imFilename = "./image/scanned-form.jpg"
print("Reading image to align : ", imFilename);
im = cv2.imread(imFilename, cv2.IMREAD_COLOR)
print("Aligning images ...")
# Registered image will be resotred in imReg.
# The estimated homography will be stored in h.
imReg, h = alignImages(im, imReference)
# Write aligned image to disk.
outFilename = "aligned.jpg"
print("Saving aligned image : ", outFilename);
cv2.imwrite(outFilename, imReg)
# Print estimated homography
print("Estimated homography : \n", h)
https://www.learnopencv.com/image-alignment-feature-based-using-opencv-c-python/
*請認真填寫需求信息,我們會在24小時內與您取得聯系。