將左邊的像素組視為矩形的數學邏輯是什么?

uj5u.com熱心網友回復:
下面是評論中的想法的實作。該方法是:
- 找到旋轉后的影像。
- 找到旋轉后的矩形邊界框 計算這個旋轉的包圍盒的面積和輪廓的面積
- 比較兩者。
- 比較這兩者。如果輪廓線的面積至少是旋轉后的邊界盒面積的80%(或任意的閾值),那么我們就認為它是矩形的 。
下面是一個影像處理管道的可視化圖輸入影像
-> 閾值 -> 檢測到的旋轉的矩形邊界框 -> 掩碼
17719.0
掩膜面積。20603.0
對比面積百分比:86.002%
它是一個矩形!
對于另一幅影像
輸入影像->閾值->檢測到的旋轉的矩形邊界框->掩碼
13395.5
掩膜面積。19274.5
對比面積百分比:69.499%。
它不是一個矩形!
你沒有指定語言,所以這里有一個使用Python OpenCV的簡單實作
import cv2
import numpy as np
# 加載影像,轉換為灰度,大津的閾值為二進制影像
image = cv2.imread('1.png')
mask = np.zeros(image.shape, dtype=np.uint8)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(grey, 0, 255, cv2.THRESH_BINARY_INV cv2.THRESH_OTSU)[1] 。
# 查找等高線,查找旋轉的矩形,查找等高線區域
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1] 。
contour_area = cv2.contourArea(cnts[0])
print('contour area: {}'.format(contour_area))
rect = cv2.minAreaRect(cnts[0])
box = np.int0(cv2.boxPoints(rect))
cv2.drawContours(image, [box], 0, (36,255,12), 3)
# 找出旋轉包圍盒的面積并繪制到遮罩影像上
mask_area = cv2.contourArea(box)
cv2.drawContours(mask, [box], 0, (255,255,255), -1)
print('mask area: {}'.format(mask_area))
# 比較面積并計算百分比
rectangular_threshold = 80
percentage = (contour_area / mask_area) * 100
print('Compared area percentage: {:.3f}%'.format(percent))
if percentage > rectangular_threshold:
print('它是一個矩形!')
否則。
print('It is not a rectangle!')
# 顯示
cv2.imshow('image', image)
cv2.imshow('thresh', thresh)
cv2.imshow('mask', mask)
cv2.waitKey()
uj5u.com熱心網友回復:
這和其中一個評論很相似(邊界框和檢查內部面積)。 我建議你使用面積和周長的方程來制作一個更強大和可配置的形狀測驗器。
-在感興趣的形狀周圍獲得一個擬合的邊界盒。
-檢查面積:blob 的像素數應大約等于 A(blob):L*W(旋轉的邊界框)
-檢查周長:blob 的像素數應大約等于 A(blob):L*W(旋轉的邊界框)
-檢查周長。運行一個邊緣變換(如Canny或類似的),并將邊緣像素的數量與矩形周長方程進行比較。P(blob):2W 2H(旋轉包圍盒)在邊緣影像上運行hough線,并檢查正交性,如果這對你來說是一個重要的引數,可以考慮另一個適配性估計器。
基本上,在您檢查形狀適配性的任何時候,您通常希望圍繞您關心的形狀的哪些方面(即干凈的邊緣、垂直的角落、內部填充、直的邊緣等)來檢查各種適配性估計器,并且您對這些估計器中的每一個進行加權或系結,以創建您所追求的適當的綜合特異性。
編輯:(代碼和補充解釋)。因此,為了明確你的例子,我同意面積是最強的健身估計。 但是,在一般的形狀識別中(圓形、正方形、長方形、復雜的形狀如葉子等),跟蹤幾個健身估計器往往是有用的,這樣你就可以真正撥出你關心的東西和你不關心的東西。 我在你的樣本中增加了一個額外的(完全偽造的)形狀,以證明單靠面積可能不太可靠的地方(在一個干凈的矩形中的切口)。 正如你所看到的,面積對外部形狀錯誤如突起非常敏感,但周長對內部形狀錯誤更敏感。 (這對你來說可能重要,也可能不重要,但我認為這很有趣,可能會有幫助)。) 我添加了一個額外的引數(周長與面積之比),這是一個整潔的指標,用于估計形狀的復雜性(特別是在葉子中)。
代碼:
#include <stdio.h>
#include <opencv2/opencv.hpp>
#include <Windows.h>
#include <string>
using namespace std;
使用名字空間cv;
void drawOrientedBoundingBox(Mat img, RotatedRect obb, Scalar color)
{
Point2f vertices[4];
obb.points(vertices);
for (int i = 0; i < 4; i )
line(img, vertices[i], vertices[(i 1) % 4], color, 2);
}
int main(int argc, char** argv)
{
//玩弄這些東西來撥弄你所關心的東西(在多個樣本影像中)。
double areaFitHigh = 1.2;
double areaFitLow = 0.8;
double perimFitHigh = 1.05;
double perimFitLow = 0.85;
std::string fileName = "C:/Local Software/voyDICOM/resources/images/RectTester.jpg" 。
Mat tempImage = imread(fileName, cv::IMREAD_GRAYSCALE)。
Mat bwImg;
cv::threshold(tempImage, bwImg, 0, 255, cv::THRESH_OTSU)。)
Mat contImg = Mat(bwImg.rows, bwImg.cols, CV_8UC3, Scalar(0, 0, 0) );
vector<vector<Point> > contours;
findContours(bwImg, contours, RETR_LIST, CHAIN_APPROX_NONE)。
bool areaFitnessFlag = false。
bool perimFitnessFlag = false。
for (size_t i = 0; i < contours.size(); i )
{
std::string contourName = "S_" std::to_string(i);
std::cout << "-------------Contour Detected------------" << std::endl;
std::cout << contourName << std::endl;
如果(contours[i].size() >= 2 * bwImg.cols 2 * bwImg.rows - 4)
{
std::cout << "影像邊界......不知道如何讓findContours在前面不檢測這個" << std::endl。
繼續。
}
RotatedRect obb = minAreaRect(contours[i])。
//為除錯目的繪制圖形
drawOrientedBoundingBox(contImg, obb, Scalar(255, 0, 0))。
drawContours(contImg, contours, static_cast<int> (i), Scalar(0, 0, 255), 2);
putText(contImg, contourName, obb.center, cv::FONT_HERSHEY_DUPLEX, 1, cv::Scalar(0, 255, 0), 1, false)。
//進行適配性檢查
double areaBlob = contourArea(contours[i]);
double areaOBB = obb.size.area();
double perimeterBlob = contours[i].size();
double perimeterOBB = 2 * obb.size.width 2 * obb.size.height。
double perimToArea = 0;
if (areaBlob > 0) { perimToArea = perimeterBlob / areaBlob; }
std::cout << "面積。" << areaBlob << " , " << areaOBB << std::endl;
std::cout << "周長。" << perimeterBlob << " , " << perimeterOBB << std::endl;
std::cout << "周長與面積之比。" << perimToArea << std::endl;
double areaFitness = 0;
if (areaOBB > 0) { areaFitness = areaBlob / areaOBB; }
std::cout << "區域健身。" << areaFitness << std::endl;
double perimeterFitness = 0;
if (perimeterOBB > 0) { perimeterFitness = perimeterBlob / perimeterOBB; }
std::cout << "Perimeter Fitness: " << perimeterFitness << std::endl;
if (areaFitness > areaFitHigh || areaFitness < areaFitLow)
{ areaFitnessFlag = false; }
否則
{ areaFitnessFlag = true; }
如果(perimeterFitness > perimFitHigh || perimeterFitness < perimFitLow)
{ perimFitnessFlag = false; }
否則
{ perimFitnessFlag = true; }
如果(areaFitnessFlag && perimFitnessFlag)
{ std::cout << "這是一個矩形!" << std::endl; }
否則
{ std::cout << "這不是一個矩形..." << std::endl; }
}
namedWindow("Original", WINDOW_AUTOSIZE)。
imshow("Original", tempImage);
namedWindow("Thresh", WINDOW_AUTOSIZE);
imshow("Thresh", bwImg);
namedWindow("Contours", WINDOW_AUTOSIZE);
imshow("Contours", contImg);
waitKey(0);
system("pause")。
回傳0。
}
有用的鏈接:
https://docs.opencv.org/master/df/dee/samples_2cpp_2minarea_8cpp-example.html
https://docs.opencv.org/master/db/dd6/classcv_1_1RotatedRect.html
https://learnopencv.com/contour-detection-using-opencv-python-c/
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/331086.html
標籤:
上一篇:N應該被分割成多少個數字的總和
下一篇:無與美麗的湯

