python - 如何根据工作 Python 代码在 iPhone 应用程序的 opencvWrapper 文件中创建 OpenCV 函数 findcontour
问题描述
我已经在我的 iPhone 应用程序中集成了 OpenCV,并设法拍了一张照片,然后使用以下代码对其进行处理。现在我想实现 findcontour 函数以获取轮廓和层次结构,就像我在 Python 中那样(下面的代码)。任何人都可以协助使用此代码吗?
// OpenCVWrapper.mm
@implementation OpenCVWrapper : NSObject
+(UIImage *)ConvertImage:(UIImage *)image {
cv::Mat mat;
UIImageToMat(image, mat);
cv::Mat median;
cv::medianBlur(mat, median, 3);
cv::Mat gray;
cv::cvtColor(median, gray, CV_RGB2GRAY); //or use COLOR_BGR2GRAY
cv::Mat denoise;
cv::fastNlMeansDenoising(gray, denoise, 30.0, 7, 21);
//here I want to enter the converted Python code from below in order to get the largest contour of the image
//cv::findContours(denoise, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE);
UIImage *binImg = MatToUIImage(contour);
return binImg;
}
@end
Python代码是:
image, contours, hierarchy = cv2.findContours(denoise,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
contours = [(c, cv2.contourArea(c)) for c in contours]
# sort contours list by area, biggest first
contours = sorted(contours, key=lambda c: c[1], reverse=True)
cnt = contours[0]
img = cv2.drawContours(frame, cnt, 0, (0,255,0), 2)
我实际上不确定是否可以处理 UIImage 然后仅返回轮廓(透明背景),以便可以将其覆盖到视频流中。这是 ViewController 中使用 captureOutput 的代码:
func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!,
from connection: AVCaptureConnection!) {
guard let uiImage = imageFromSampleBuffer(sampleBuffer: sampleBuffer) else { return }
DispatchQueue.main.async(execute: {
self.imageView.image = OpenCVWrapper.convert(uiImage) ///I am really not sure whether this is the right code to show the uiImage on top of the live stream. Have not really gotten to that issue as yet, but any assistance is welcome
解决方案
实际上,我想通了。这是工作解决方案:
//Find the contours. Use the contourOutput Mat so the original image doesn't get overwritten
std::vector<std::vector<cv::Point> > contours;
cv::Mat contourOutput = canny.clone();
cv::findContours( contourOutput, contours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE );
int largest_area=0;
int largest_contour_index=0;
// iterate through each contour.
for( int i = 0; i< contours.size(); i++ )
{
// Find the area of contour
double a=contourArea( contours[i],false);
if(a>largest_area){
largest_area=a;std::cout<<i<<" area "<<a<<std::endl;
// Store the index of largest contour
largest_contour_index=i;
}
}
cv::Mat contourImage(canny.size(), CV_8UC3, cv::Scalar(0,0,0));
cv::Scalar color;
color = cv::Scalar(255, 0, 0);
cv::drawContours(contourImage, contours, largest_contour_index, color);
推荐阅读
- ios - 如何在 swift 5 中使用 Alamofire multipartFormData 连同图像一起发送数据
- sql - 如何找到从 10 月 1 日至今的每一天的价格总和
- python-3.x - 如何在 python bigtable 中进行分页
- r - 检测字符串向量中的长度和字母数字模式
- reactjs - React - 使用柯里化函数时如何防止重新渲染
- python - 需要使用 lxml etree Python 将元素值替换为 Mix Content
- java - 遇到“java.awt.HeadlessException:未设置 X11 DISPLAY 变量,但该程序执行了需要它的操作。”
- replication - 如何在几个 Tarantool 路由器之间设置盒式应用程序复制?
- powershell - Powershell更改文件夹内一个子文件夹(按文件夹名称)内的部分文件名
- project-reactor - Reactor Flux 抛出非法ArgumentException - 怀疑是由于 bufferTimeout