Android 는 OpenCV 를 기반 으로 QR QR QR 코드 검 사 를 실현 합 니 다.
QR 코드(영어:빠 른 응답 코드;모두 빠 른 응답 매트릭스 코드 라 고 함)는 QR 코드 의 일종 으로 1994 년 일본 DENSO WAVE 사가 발명 했다.QR 은 영문 Quick Response 의 줄 임 말,즉 빠 른 반응 에서 나온다.왜냐하면 발명 자 는 QR 코드 가 그 내용 을 신속하게 디 코딩 할 수 있 기 를 원 하기 때문이다.QR 코드 는 네 가지 표준화 코드 모드(숫자,알파벳 숫자,바이트(바 이 너 리)와 일본어(Shift)를 사용 합 니 다.JIS))데 이 터 를 저장 합 니 다.QR 코드 는 일본 에서 흔히 볼 수 있 으 며 현재 일본 에서 가장 통용 되 는 2 차원 공간 바코드 로 세계 각국 에서 휴대 전화 읽 기 코드 조작 에 널리 사용 되 고 있다.QR 코드 는 일반 1 차원 바코드 보다 빠 른 읽 기와 더 큰 저장 자료 용량 을 가지 고 있 으 며 1 차원 바코드 처럼 스 캔 할 때 직선 조준 스캐너 가 필요 하지 않다.따라서 그 응용 범 위 는 제품 추적,물품 식별,문서 관리,재고 마 케 팅 등 분야 로 확대 되 었 다.위 키 백과
QR QR 코드 형식
QR 사 이 즈 는 정사각형 으로 흔히 볼 수 있 는 흑백 2 색 입 니 다.세 구석 에'회'자의 정사각형 도안 처럼 작 게 인쇄 되 어 있다.이 세 가 지 는 디 코딩 소프트웨어 의 포 지 셔 닝 을 돕 는 도안 으로 사용 자 는 조준 할 필요 가 없다.어떤 각도 로 스 캔 하 더 라 도 자 료 는 정확하게 읽 을 수 있다.일본 QR 코드 의 표준 JIS X 0510 은 1999 년 1 월 에 발 표 됐 고 이에 대응 하 는 ISO 국제 표준 ISO/IEC 18004 는 2000 년 6 월 에 승인 을 받 았 다.덴 소 웨 이브 사 홈 페이지 자료 에 따 르 면 QR 코드 는 개방 형 기준 으로 QR 코드 의 규격 이 공 개 돼 덴 소 웨 이브 사가 보유 한 특허 권익 이지 만 운영 되 지 않 는 다.표준 QR 코드 외 에 도'미니 QR 코드'라 고 불 리 는 포맷 이 존재 하 며 QR 코드 표준 의 축소 버 전 으로 대형 스 캔 애플 리 케 이 션 을 처리 하지 못 하도록 설계 됐다.마이크로 QR 코드 역시 여러 가지 기준 이 있 고 최고 35 자 를 저장 할 수 있 습 니 다.【위 키 백과
QR QR QR 코드 구조
QR 코드 의 가장 큰 특징 은 왼쪽 위,오른쪽 위,왼쪽 아래 세 개의 대형'회'자 와 같은 흑백 간 동심원 도안 으로 QR 코드 에 포 지 셔 닝 표 시 를 식별 하고 그 중 하 나 를 잃 으 면 식별 에 영향 을 줄 수 있다.한편,바둑판 처럼 분포 되 어 있 는 큰 포 지 셔 닝 표지 와 작은 동심원 은 그 교정 표 시 를 위해 교정 식별 에 사용 된다.버 전 1 은 교정 표시 가 없고 버 전 2 는 오른쪽 아래 에 있다.그 중에서 중심 점 은 왼쪽 아래 와 오른쪽 위 에 표 시 된 외곽 테두리 의 교차점 이다.버 전 10 은 각 등거리 의 방식 으로 오른쪽 아래 에서 왼쪽 아래 와 오른쪽 위 에 표 시 된 외곽 테두리 의 연결선 에 나타난다.왼쪽 위 와 왼쪽 아래 포 지 셔 닝 표지 의 바깥쪽 테두리 의 연결선,왼쪽 위 와 오른쪽 위 에 포 지 셔 닝 표 시 된 바깥쪽 테두리 의 연결선 사이,이 네 개의 경계선 위의 등거리 점 이 서로 연결 되 고 버 전 10 등거리 가 1 개 이 며 버 전 25 는 3 개 이 며 버 전 40 은 5 개 입 니 다.위 키 백과
API
QRcodeDetector 클래스 구조
QR QR 코드 검사
public boolean detect(Mat img, Mat points)
public boolean detectMulti(Mat img, Mat points)
public String decode(Mat img, Mat points, Mat straight_qrcode)
public boolean decodeMulti(Mat img, Mat points, List<String> decoded_info, List<Mat> straight_qrcode)
public String detectAndDecode(Mat img, Mat points, Mat straight_qrcode)
public boolean detectAndDecodeMulti(Mat img, List<String> decoded_info, Mat points, List<Mat> straight_qrcode)
인자 4:straightqrcode,검 측 된 모든 QR 코드 교정 과 이치 화 된 결과 집합.[선택 가능 한 매개 변수
4.567917.반환 값:문자열 형식,디 코딩 에 실패 하면 빈 문자열 입 니 다.
조작 하 다.
/**
* QR
* author: yidong
* 2020/10/27
*/
class QRDetectActivity : AppCompatActivity() {
private lateinit var mBinding: ActivityQrDetectBinding
private lateinit var mQRCodeDetector: QRCodeDetector
private var mPhotoSavePath = ""
private lateinit var mUri: Uri
private lateinit var mSource: Mat
private lateinit var mGray: Mat
private lateinit var mOperationSheet: BottomSheetDialog
private lateinit var mSheetBinding: LayoutQrDetectOpBinding
private lateinit var mPhotoSheet: BottomSheetDialog
private lateinit var mPhotoOpBinding: LayoutPhotoOpBinding
//
private val requestCameraPermission =
registerForActivityResult(ActivityResultContracts.RequestPermission()) {
if (it) {
mPhotoSavePath =
cacheDir.path + File.separator + "${System.currentTimeMillis()}.png"
mUri = MediaStoreUtils.getIntentUri(this, File(mPhotoSavePath))
requestCamera.launch(mUri)
} else {
Toast.makeText(applicationContext, " ", Toast.LENGTH_SHORT).show()
}
}
//
private val requestStoragePermission =
registerForActivityResult(ActivityResultContracts.RequestPermission()) {
if (it) {
pickImage.launch("image/*")
} else {
Toast.makeText(applicationContext, " ", Toast.LENGTH_SHORT).show()
}
}
private val requestCamera = registerForActivityResult(ActivityResultContracts.TakePicture()) {
if (it) {
val bgr = Imgcodecs.imread(mPhotoSavePath, Imgcodecs.IMREAD_COLOR)
if (bgr.empty()) {
Toast.makeText(applicationContext, " ", Toast.LENGTH_SHORT).show()
return@registerForActivityResult
} else {
Imgproc.cvtColor(bgr, mSource, Imgproc.COLOR_BGR2RGB)
Imgproc.cvtColor(bgr, mGray, Imgproc.COLOR_BGR2GRAY)
mBinding.ivLena.showMat(mSource)
}
} else {
Toast.makeText(applicationContext, " ", Toast.LENGTH_SHORT).show()
}
}
private val pickImage = registerForActivityResult(ActivityResultContracts.GetContent()) {
if (it != null) {
val filePath = MediaStoreUtils.getMediaPath(this, it)
if (filePath.isNullOrEmpty()) {
Toast.makeText(applicationContext, " ", Toast.LENGTH_SHORT).show()
return@registerForActivityResult
}
val bgr = Imgcodecs.imread(filePath, Imgcodecs.IMREAD_COLOR)
if (bgr.empty()) {
Toast.makeText(applicationContext, " ", Toast.LENGTH_SHORT).show()
return@registerForActivityResult
} else {
Imgproc.cvtColor(bgr, mSource, Imgproc.COLOR_BGR2RGB)
Imgproc.cvtColor(bgr, mGray, Imgproc.COLOR_BGR2GRAY)
mBinding.ivLena.showMat(mSource)
}
} else {
Toast.makeText(applicationContext, " ", Toast.LENGTH_SHORT).show()
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mBinding = DataBindingUtil.setContentView(this, R.layout.activity_qr_detect)
mQRCodeDetector = QRCodeDetector()
mSource = Mat()
mGray = Mat()
val bgr = Utils.loadResource(this, R.drawable.qrcode)
Imgproc.cvtColor(bgr, mSource, Imgproc.COLOR_BGR2RGB)
Imgproc.cvtColor(bgr, mGray, Imgproc.COLOR_BGR2GRAY)
mBinding.ivLena.showMat(mSource)
createDialog()
}
private fun createDialog() {
mOperationSheet = BottomSheetDialog(this)
mSheetBinding = LayoutQrDetectOpBinding.inflate(layoutInflater, null, false)
mOperationSheet.setContentView(mSheetBinding.root)
mSheetBinding.tvDetect.setOnClickListener {
mOperationSheet.dismiss()
doDetect()
}
mSheetBinding.tvDecode.setOnClickListener {
mOperationSheet.dismiss()
doDecode()
}
mPhotoSheet = BottomSheetDialog(this)
mPhotoOpBinding = LayoutPhotoOpBinding.inflate(layoutInflater, null, false)
mPhotoSheet.setContentView(mPhotoOpBinding.root)
mPhotoOpBinding.tvCamera.setOnClickListener {
mPhotoSheet.dismiss()
requestCameraPermission.launch(
Manifest.permission.CAMERA
)
}
mPhotoOpBinding.tvPhoto.setOnClickListener {
mPhotoSheet.dismiss()
requestStoragePermission.launch(
Manifest.permission.WRITE_EXTERNAL_STORAGE
)
}
}
private fun doDetect() {
val points = Mat()
val isHasQr = mQRCodeDetector.detect(mSource, points)
if (isHasQr) {
val pointArr = FloatArray(8)
points.get(0, 0, pointArr)
Log.d(App.TAG, pointArr.toList().toString())
val tmp = mSource.clone()
for (i in pointArr.indices step 2) {
val start = Point(pointArr[i % 8].toDouble(), pointArr[(i + 1) % 8].toDouble())
val end = Point(pointArr[(i + 2) % 8].toDouble(), pointArr[(i + 3) % 8].toDouble())
Imgproc.line(tmp, start, end, Scalar(255.0, 0.0, 0.0), 8, Imgproc.LINE_8)
}
mBinding.ivResult.showMat(tmp)
tmp.release()
}
}
private fun doDecode() {
val points = Mat()
val isHasQr = mQRCodeDetector.detect(mGray, points)
if (isHasQr) {
val result = mQRCodeDetector.decode(mGray, points)
if (result.isEmpty()) {
Toast.makeText(applicationContext, " ", Toast.LENGTH_SHORT).show()
} else {
Snackbar.make(mBinding.root, " :$result", 3000).show()
}
Log.d(App.TAG, result)
} else {
Toast.makeText(applicationContext, " QRCode", Toast.LENGTH_SHORT).show()
}
}
private fun selectMedia() {
if (this::mPhotoSheet.isInitialized) {
mPhotoSheet.show()
}
}
private fun selectOps() {
if (this::mOperationSheet.isInitialized) {
mOperationSheet.show()
}
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.menu_qr_detect, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.menu_pick_photo -> selectMedia()
R.id.menu_qr_ops -> selectOps()
}
return true
}
override fun onDestroy() {
mSource.release()
mGray.release()
super.onDestroy()
}
}
결실소스 코드
github.com/onlyloveyd/…
이상 은 바로 안 드 로 이 드 가 OpenCV 를 바탕 으로 QR QR QR 코드 검 사 를 실현 하 는 상세 한 내용 입 니 다.안 드 로 이 드 OpenCV 가 QR 코드 검 사 를 실현 하 는 것 에 관 한 자 료 는 저희 의 다른 관련 글 을 주목 하 시기 바 랍 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Bitrise에서 배포 어플리케이션 설정 테스트하기이 글은 Bitrise 광고 달력의 23일째 글입니다. 자체 또는 당사 등에서 Bitrise 구축 서비스를 사용합니다. 그나저나 며칠 전 Bitrise User Group Meetup #3에서 아래 슬라이드를 발표했...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.