我使用U2NET成功地計算了一張圖片的掩碼,如下所示:
然而,正如可以看到的那樣,遮罩內部不是完全白色的,而且在遮罩外部,即左邊的部分,也可以觀察到一些不需要的偽影。
我正試圖使用擴張和侵蝕操作來解決上述兩個問題,但我認為這是一個錯誤的方法,因為它沒有產生預期的結果。
我正在做類似于以下的事情,但并沒有解決這個問題:
我正在做類似于以下的事情。
from PIL import ImageFilter
dilation_img = image.filter(ImageFilter.MaxFilter(15)
erotion_img = dilation_img.filter(ImageFilter.MinFilter(15)
uj5u.com熱心網友回復:
你可以使用Otsu的演算法動態地對影像進行閾值處理。之后,你可以用OpenCV的輪廓線在它們上面畫圖來填補任何漏洞。我不確定U2Net在遮蔽時能回傳什么數值范圍,但你也可能只是手動設定一個小的閾值~50就可以了。
import cv2
import numpy as np
#加載圖片 #加載圖片
img = cv2.imread("mask.jpg", cv2.IMREAD_GRAYSCALE) 。
# otsu 閾值處理0,255, cv2.THRESH_BINARY cv2.THRESH_OTSU)。
# show"Mask"/span>, mask)。
cv2.waitKey(0)。
# 關閉里面的所有東西。
contour, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) 。
# get the biggest contour # returns _, contours, _ if using OpenCV 3
biggest_area = -1;
biggest = None;
for con in contour:
area = cv2.contourArea(con);
if biggest_area < area:
biggest_area = area;
biggest = con;
# 填充等高線。
cv2.drawContours(mask, [biggest], -1, 255, -1) 。
# showing
cv2.imshow("Filled Mask", mask)。
cv2.waitKey(0)。
uj5u.com熱心網友回復:
一種解決方案是使用二進制閾值處理,使不是白色但接近白色的部分成為白色。
- 使用
結果2作為原遮罩的遮罩,方法如下:
...
//assumptions: white=255, black=0
threshold = 128;//你可以改變它以給予更多的權重 用于白色 或者黑色
for(...回圈 所有的像素)
for(...)
{
if((OrginalMask[x,y] > threshold) && (result2[x,y] < threshold)
finalResult[x,y] = result2[x,y];//去除遮罩外不需要的偽影。
else if ((OrginalMask[x,y] < threshold) && (result2[x,y] > threshold))
finalResult[x,y] = result2[x,y];//使面具內部完全變白。
else
finalResult[x,y] = OrginalMask[x,y]。
uj5u.com熱心網友回復:
雖然我認為這個問題可以通過一個很好的二進制閾值來解決(正如另一個答案中所說的),但添加一個額外的基本形態學水平應該可以使它對明顯更臟的影像更加強大。 (對不起,這是用C 語言寫的)
我使用了一個任意的二進制閾值。
我使用了一個任意的二進制閾值來演示這個概念,但是如果可以的話,我建議使用一個基于統計學的閾值(例如大津方法)。
稍微解釋一下代碼:閾值將灰度影像轉換為二進制。 打開去除由閾值操作留下的外部噪聲(任何小條狀、片狀或像素噪聲)。 關閉填補任何內部漏洞。 "打開 "和 "關閉 "只是按照特定的順序對擴張和侵蝕的組合進行命名,以便在不改變底層物件的尺寸/形狀的情況下達到預期的效果。
#include <stdio.h>
#include <opencv2/opencv.hpp>
#include <Windows.h>
#include <string>
使用名稱空間cv。
int main(int argc, char** argv)
{
/C:/Local Software/voyDICOM/resources/images/oXsnC.jpg
std::string fileName = "C:/Local Software/voyDICOM/resources/images/oXsnC.jpg"/span>。
Mat tempImage = imread(fileName, cv::IMREAD_GRAYSCALE)。
Mat bwImg;
//二進制閾值(這兩種方法都可以,otsu只是得到一個"更聰明"的閾值,而不是一個硬編碼的閾值)。
cv::threshold(tempImage, bwImg, 150, 255, cv::THRESH_BINARY) 。
//cv::threshold(tempImage, bwImg, 0, 255, cv::THRESH_OTSU) 。
Mat openedImage。
//打開
cv::erode(bwImg, openedImage, cv::getStructuringElement(cv::MORPH_CROSS, cv::Size(3, 3)), cv: :Point(-1, -1), 2)。)
cv::dilate(openImage, openedImage, cv::getStructuringElement(cv::MORPH_CROSS, cv::Size(3, 3)), cv: :Point(-1, -1), 2)。)
Mat closedImg;
//閉合
cv::dilate(openImage, closedImg, cv::getStructuringElement(cv::MORPH_CROSS, cv::Size(3, 3)),cv.:getStructuringElement(cv::MORPH_CROSS) :Point(-1,-1),5)。)
cv::erode(closedImg, closedImg, cv::getStructuringElement(cv::MORPH_CROSS, cv::Size(3, 3)), cv: :Point(-1, -1), 5)。)
namedWindow("Original", WINDOW_AUTOSIZE) 。
imshow("Original", tempImage)。
namedWindow("Thresh", WINDOW_AUTOSIZE) 。
imshow("Thresh", bwImg)。
namedWindow("Opened", WINDOW_AUTOSIZE) 。
imshow("Opened", openedImage)。
namedWindow("Closed", WINDOW_AUTOSIZE)。
imshow("Closed", closedImg)。
waitKey(0)。
system("pause")。
return 0;
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/326124.html
標籤:
下一篇:Python影像的串行輸出





