【1】此代码提取手机屏上面的子像素并定位,代码仅供参考。

效果图

  

【2】代码

(1).h和.cpp文件


#pragma once
#include "pch.h"
#include <iostream>
#include <vector>
#include <opencv2/opencv.hpp>using namespace std;
using namespace cv;//图片旋转调整,返回一个斜率
float WrapImage(Mat image);//得到一个像素周围灰度值最大的像素点
Point2f GetMaxPixel(Mat gray, Point2f p);//阈值分割及子像素点提取
vector<Point2f> GetPixel(Mat image);//像素点根据斜率进行调整及从小到大排序
vector<Point2f> AdjustPixel(vector<Point2f> pt, float k);//根据每行子像素的y坐标相差4个像素点以内来获得各行子像素
vector <vector<Point2f>>GetRowPixel(vector<Point2f> pt, float k);//连接各行子像素成直线
void LineRow(Mat origin, vector<vector<Point2f>> row, string str);
#include "pch.h"
#include"AmledAlgorithm.h"bool cmp(Point2f a, Point2f b)
{return a.y < b.y;
}//图片旋转调整,返回一个斜率
float WrapImage(Mat image)
{//灰度、二值化、膨胀Mat gray, bin, dil;cvtColor(image, gray, COLOR_RGB2GRAY);threshold(gray, bin, 10, 255, THRESH_BINARY);Mat element = getStructuringElement(MORPH_RECT, Size(5, 5));dilate(bin, dil, element);//轮廓最小矩形,寻找旋转角度和旋转中心vector <vector<Point>> contours;vector<Vec4i> hierarchy;findContours(dil, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE);Rect boundrect;RotatedRect rect;for (int i = 0; i < contours.size(); i++){Point2f r[4];rect = minAreaRect(contours[i]);boundrect = boundingRect(Mat(contours[i]));rect.points(r);rectangle(dil, Point(boundrect.x, boundrect.y), Point(boundrect.x + boundrect.width, boundrect.y + boundrect.height), Scalar(255, 255, 255), 2, 8);for (int j = 0; j < 4; j++){line(dil, r[j], r[(j + 1) % 4], Scalar(255, 255, 255), 2, 8);}}float angle = rect.angle / 180 * CV_PI;return tan(angle);
}//得到一个像素周围灰度值最大的像素点
Point2f GetMaxPixel(Mat gray, Point2f p)
{//八领域像素点int a[8][2] = { { -1, -1 }, { 0, -1 }, { 1, -1 }, { -1, 0 }, { 1, 0 }, { -1, 1 }, {0, 1 }, { 1, 1 } };Point2f maxPoint;maxPoint.x = p.x;maxPoint.y = p.y;for (int i = 0; i < 8; i++){Point2f tmp;tmp.x = p.x + a[i][0];tmp.y = p.y + a[i][1];//对一个像素的邻域8个像素进行比较,选取灰度值最高的像素点作为子像素(灯珠)的中心      if (gray.at<uchar>(maxPoint) < gray.at<uchar>(tmp)){maxPoint.x = tmp.x;maxPoint.y = tmp.y;}}return maxPoint;
}//阈值分割及子像素点提取
vector<Point2f> GetPixel(Mat image)
{Mat gray;cvtColor(image, gray, COLOR_BGR2GRAY);Mat th_img;threshold(gray, th_img, 40, 255, THRESH_BINARY);//连通域获取中心坐标Mat labels, stats, centroids;int nccomps = connectedComponentsWithStats(th_img, labels, stats, centroids);vector<Point2f> pt;for (int i = 0; i < centroids.rows; i++){Point2f p;p.x = centroids.at<uchar>(i, 0);p.y = centroids.at<uchar>(i, 1);Point2f maxPoint = GetMaxPixel(gray, p);pt.push_back(p);}//返回所有子像素点坐标return pt;
}//像素点根据斜率进行调整及从小到大排序
vector<Point2f> AdjustPixel(vector<Point2f> pt, float k)
{for (int i = 0; i < pt.size(); i++){pt[i].y = pt[i].y - k * pt[i].x;}sort(pt.begin(), pt.end(), cmp);return pt;
}//根据每行子像素的y坐标相差4个像素点以内来获得各行子像素
vector <vector<Point2f>>GetRowPixel(vector<Point2f> pt, float k)
{vector <vector<Point2f>> row;for (int i = 0; i < pt.size(); i++){vector<Point2f> sig_row;sig_row.push_back(pt[i]);Point2f pp = pt[i++];while ((pt[i].y )< (pp.y + 4) && (pt[i].y > (pp.y - 4) && (pt.size() - 1)>0)){break;}i--;row.push_back(sig_row);}  for (int i = 0; i < row.size(); i++){for (int j = 0; j < row[i].size(); j++){for (int k = j; k < row[i].size(); k++){if (row[i][j].x >= row[i][k].x)swap(row[i][j], row[i][k]);}}}//反转,转换回原图像坐标for (int i = 0; i < row.size(); i++){for (int j = 0; j < row[i].size(); j++){row[i][j].y += row[i][j].x*k;}}return row;}//连接各行子像素成直线
void LineRow(Mat origin, vector<vector<Point2f>> row, string str)
{for (int i = 0; i < row.size(); i++){for (int j = 0; j < row[i].size() - 1; j++){line(origin, row[i][j], row[i][j + 1], Scalar(0, 255, 255), 0.05);}}imwrite(str, origin);}

(2)主程序

// AMOLEDDetecd.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//#include "pch.h"
#include <iostream>
#include <vector>
#include <opencv2/opencv.hpp>
#include "AmledAlgorithm.h"using namespace std;
using namespace cv;int _tmain(int argc, char *argv[])
{string dir_path = "E:\\image-R\\";vector<string> file_vec;glob(dir_path + "*.bmp", file_vec, false);Mat image = imread("E:\\image-R\\img_R255.bmp");float k = WrapImage(image);vector<Point2f> pt = GetPixel(image);vector<Point2f> pot = AdjustPixel(pt, k);vector <vector<Point2f>> p_row = GetRowPixel(pot, k);string filename = "F:\\image-R\\img_R255.bmp";LineRow(image, p_row, filename);//RGB三通道9张灰阶图像,进行9次循环for (int i = 0; i < 9; i++){if (file_vec[i] == "E:\\image-R\\img_R255.bmp")continue;Mat image = imread(file_vec[i]);string str = file_vec[i];str[0] = 'F';LineRow(image, p_row, str);}system("pause");waitKey(0);return 0;
}

【17】AMOLED屏幕子像素定位相关推荐

  1. pentile 子像素_“周冬雨排列”登上热搜,不同排列方式的OLED屏幕到底有什么区别?...

    原标题:"周冬雨排列"登上热搜,不同排列方式的OLED屏幕到底有什么区别? 2020年,不少手机厂商都向屏幕方面发力,开启了一条全新的竞争赛道.高素质的OLED屏幕基本已经成为了旗 ...

  2. pentile 子像素_OLED像素排列

    现在的手机,屏幕越来越大,分辨率也越来越高,很多人在购买手机时,往往认为,分辨率 越高, 屏幕显示效果越清晰.实际上,这种想法是不全面的. 屏幕的材质以及子像素的排列 方式也是影响屏幕显示效果的重要因 ...

  3. pentile 子像素_三星和索尼OLED子像素排列方式对比 有哪些差异?

    目前已经有很多 VR 头戴设备在市面上进行发售,不同的厂家都因为价格定位的差异而选择不同的硬件解决方案.在其中最影响体验效果的自然是 下面,我们就以三星和索尼 的 OLED 产品为例进行浅要分析. 三 ...

  4. amoled led 排列_科普:为何AMOLED屏幕不用RGB排列

    科普:为何AMOLED屏幕不用RGB排列 先简单介绍一下,AMOLED屏是英文Active-matrix organic light emitting diode的简写,拥有超高的色彩还原能力和色彩逼 ...

  5. amoled led 排列_为何AMOLED屏幕不用RGB排列?

    OFweek显示网讯 AMOLED屏幕为什么不采用RGB排列呢? 先简单介绍一下,AMOLED屏是英文Active-matrix organic light emitting diode的简写,拥有超 ...

  6. OpenCv-C++-亚像素级别角点检测(检测子像素中的corner的位置)

    使用亚像素级别角点检测,返回角点的浮点数值,它的精度比整数像素更准确.可以用cornerSubPix()函数将角点定位到子像素,从而取得亚像素级别的角点检测效果. 使用函数: void cv::cor ...

  7. AMOLED屏幕的一些固有缺陷

    AMOLED屏幕的一些固有缺陷 在显示效果.对比度,阳光下的表现.黑色的表现.可视角度等诸多方面,AMOLED屏幕都是时下最优秀的屏幕.抛开Pentile次像素排列的问题不说,AMOLED仍有一些硬伤 ...

  8. OpenCV检测子像素中的角点位置

    OpenCV检测子像素中的角点位置 检测子像素中的角点位置 目标 代码 结果 检测子像素中的角点位置 目标 在本教程中,您将学习如何: 使用OpenCV函数cv :: cornerSubPix查找更精 ...

  9. 【移动端】屏幕、像素、视口、 viewport 控制

    移动端开发 文章目录 移动端开发 学习内容 学习目标 移动端特点 相关概念 屏幕相关 屏幕大小 屏幕分辨率 像素相关 物理像素 / 设备像素 设备独立像素 / 设备无关像素 Retina 屏幕 CSS ...

最新文章

  1. linux代码动态分析软件,举例分析Linux动态库和静态库
  2. OSChina 周一乱弹 —— 把朋友圈的锦鲤全都抓走
  3. 写一个图片预览器(react-native),温习一下初中数学
  4. Python字典排序sorted无效,用匿名函数lambda解决
  5. C++ STL之vector常用方法
  6. FFmpeg options
  7. 【渝粤教育】21秋期末考试财务管理10164k2
  8. th:text为null报错_为什么建议你用nullptr而不是NULL?
  9. 新星云集!CVPR 论文分享会圆桌论坛:计算机视觉科研​之“路”
  10. 今天的你将感谢_今天感谢开发人员:这是
  11. 剖析供应链攻击的防范
  12. 【数据分析就业实战】——缺失值的常见处理方法
  13. textfield获取其中内容_冲压工艺流程,常见冲压缺陷及消除方法,46页内容全面介绍冲压...
  14. 实现简单的字符串队列
  15. IDEA利用wsdl文件生成WebService调用接口的方法
  16. PS给证件照换背景颜色
  17. java反向查找dns_windows – 反向DNS查找
  18. 1217: 青蛙(二)
  19. (1)从1开始写一个操作系统
  20. html+javascript实现广告窗自由浮动

热门文章

  1. 俄罗斯方块_c++实现
  2. 代码实现3X3矩阵求逆(C语言 用伴随矩阵实现)
  3. dir命令(dir命令的功能是什么)
  4. 知识图谱软件哪个平台好?知识图谱技术有哪些?
  5. 看了那么多写作技巧的书为什么还是写不出东西?
  6. B站新顶流多恐怖? 8位千粉UP主缔造1000万播放
  7. 内部推荐!陌陌深度学习实验室招聘算法实习生
  8. linux如何离线安装rdesktop,rdesktop 的安装使用
  9. 一部8K立体视频,列举其主要参数,并给出依据这些参数计算其码率的方法。8K视频推广应用面临的主要问题你认为包括哪些方面。...
  10. 【IC萌新虚拟项目】ppu模块的编译环境搭建与RTL编译